From 7c5ef541a6210b226434ad91ad9713c004d3535a Mon Sep 17 00:00:00 2001 From: GregcodeOhm Date: Tue, 7 Jul 2026 00:27:55 +0200 Subject: [PATCH] FIX #38981 product/stats/facture.php fatal error when invoice module is disabled (#39049) The massaction sendEmail feature added to this page for v24 by 8f0b7e3f (#37937) reads $conf->invoice->dir_output and includes core/actions_massactions.inc.php on every page load. When the invoice module is disabled, dir_output is empty, so the include hits its protection ('$objectclass or $uploaddir was not defined') and exits. The referers tab built by product_prepare_head() links to this page unconditionally, so any v24 install without the invoice module gets a fatal error on the product referers tab. In 23.0 the page had no mass action code and rendered fine without the module. Make the whole massaction machinery conditional on isModEnabled('invoice'): do not read dir_output, do not propose the mass action, neutralize $massaction and skip the actions_massactions include when the module is off. This restores the 23.0 behavior for installs without the invoice module and changes nothing when the module is enabled. Signed-off-by: GregcodeOhm Co-authored-by: GregcodeOhm Co-authored-by: Claude Fable 5 --- htdocs/product/stats/facture.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/htdocs/product/stats/facture.php b/htdocs/product/stats/facture.php index 110f627a1f7..3f524dbc9ec 100644 --- a/htdocs/product/stats/facture.php +++ b/htdocs/product/stats/facture.php @@ -137,7 +137,7 @@ $result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product $toselect = GETPOST('toselect', 'array:int'); $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'invoicelist'; $massaction = GETPOST('massaction', 'alpha'); -$diroutputmassaction = $conf->invoice->dir_output.'/temp/massgeneration/'.$user->id; +$diroutputmassaction = isModEnabled('invoice') ? $conf->invoice->dir_output.'/temp/massgeneration/'.$user->id : ''; if (GETPOST('cancel', 'alpha')) { $action = 'list'; @@ -146,6 +146,10 @@ if (GETPOST('cancel', 'alpha')) { if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; } +if (!isModEnabled('invoice')) { + // The mass actions of this page rely on the invoice module (objects, permissions, upload directory) + $massaction = ''; +} $arrayfields = array( 'f.ref' => array('label' => "Ref", 'checked' => '1', 'position' => 5), 's.nom' => array('label' => "ThirdParty", 'checked' => '1', 'position' => 50), @@ -164,9 +168,10 @@ $formother = new FormOther($db); -$arrayofmassactions = array( - 'presend' => img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), -); +$arrayofmassactions = array(); +if (isModEnabled('invoice')) { + $arrayofmassactions['presend'] = img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"); +} $massactionbutton = $form->selectMassAction('', $arrayofmassactions); $arrayofselected = is_array($toselect) ? $toselect : array(); $selectedfields = (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); @@ -180,7 +185,7 @@ $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } -if (empty($reshook)) { +if (empty($reshook) && isModEnabled('invoice')) { $objectclass = 'Facture'; $objectlabel = 'Invoices'; $permissiontoread = $user->hasRight("facture", "lire");