118 if (!is_array(
$conf->modules_parts[
'hooks']) || empty(
$conf->modules_parts[
'hooks'])) {
123 if (!is_array($arraycontext)) {
124 $arraycontext = array($arraycontext);
130 if (!array_diff($arraycontext, $this->contextarray)) {
134 $this->contextarray = array_unique(array_merge($arraycontext, $this->contextarray));
136 $foundcontextmodule =
false;
139 foreach (
$conf->modules_parts[
'hooks'] as
$module => $hooks) {
145 foreach ($arraycontext as
$context) {
146 if (is_array($hooks)) {
147 $arrayhooks = $hooks;
149 $arrayhooks = explode(
':', $hooks);
152 if (!in_array(
$context, $arrayhooks) && !in_array(
'all', $arrayhooks)) {
160 $path =
'/'.$module.
'/class/';
161 $actionfile =
'actions_'.$module.
'.class.php';
165 $controlclassname =
'Actions'.ucfirst(
$module);
167 $actionInstance =
new $controlclassname($this->db);
168 '@phan-var-force CommonHookActions $actionInstance';
171 $priority = (!property_exists($actionInstance,
'priority') || empty($actionInstance->priority)) ? 50 : $actionInstance->priority;
176 $foundcontextmodule =
true;
179 $stringtolog =
'context='.$context.
'-path='.$path.$actionfile.
'-priority='.$priority;
180 dol_syslog(get_class($this).
"::initHooks Loading hooks: ".$stringtolog, LOG_DEBUG);
182 dol_syslog(get_class($this).
"::initHooks Failed to load hook in ".$path.$actionfile, LOG_WARNING);
191 if ($foundcontextmodule) {
192 foreach ($arraycontext as
$context) {
193 if (!empty($this->hooksSorted[
$context])) {
194 ksort($this->hooksSorted[
$context], SORT_NATURAL);
220 if (
isModEnabled(
'debugbar') && function_exists(
'debug_backtrace')) {
221 $trace = debug_backtrace();
222 if (isset($trace[0])) {
223 $hookInformations = [
225 'contexts' => $this->contextarray,
226 'file' => $trace[0][
'file'],
227 'line' => $trace[0][
'line'],
230 $hash = md5(json_encode($hookInformations));
231 if (!empty($this->hooksHistory[$hash])) {
232 $this->hooksHistory[$hash][
'count']++;
234 $hookInformations[
'count'] = 1;
235 $this->hooksHistory[$hash] = $hookInformations;
240 if (!is_array($this->hooks) || empty($this->hooks)) {
243 if (!is_array($parameters)) {
244 dol_syslog(
'executeHooks was called with a non array $parameters. Surely a bug.', LOG_WARNING);
245 $parameters = array();
248 $parameters[
'context'] = implode(
':', $this->contextarray);
252 $hooktype =
'addreplace';
254 if (in_array($method, array(
256 'dashboardAccountancy',
257 'dashboardActivities',
258 'dashboardCommercials',
259 'dashboardContracts',
261 'dashboardEmailings',
262 'dashboardExpenseReport',
264 'dashboardInterventions',
267 'dashboardOpensurvey',
269 'dashboardOrdersSuppliers',
270 'dashboardProductServices',
273 'dashboardSpecialBills',
274 'dashboardSupplierProposal',
275 'dashboardThirdparties',
277 'dashboardUsersGroups',
278 'dashboardWarehouse',
279 'dashboardWarehouseReceptions',
280 'dashboardWarehouseSendings',
285 'formBuilddocOptions',
288 $hooktype =
'output';
293 $localResArray = array();
295 $this->resNbOfHooks = 0;
299 $modulealreadyexecuted = array();
302 foreach ($this->hooksSorted as
$context => $modules) {
303 if (!empty($modules)) {
304 '@phan-var-force array<string,CommonHookActions> $modules';
306 foreach ($modules as
$module => $actionclassinstance) {
311 if (in_array(
$module, $modulealreadyexecuted)) {
316 if (!method_exists($actionclassinstance, $method)) {
320 $this->resNbOfHooks++;
325 $actionclassinstance->error =
'';
326 $actionclassinstance->errors = array();
327 $actionclassinstance->warnings = array();
331 dol_syslog(get_class($this).
"::executeHooks Qualified hook found (hooktype=".$hooktype.
"). We call method ".get_class($actionclassinstance).
'->'.$method.
", context=".
$context.
", module=".
$module.
", action=".$action.((is_object(
$object) && property_exists(
$object,
'id')) ?
', object id='.$object->id :
'').((is_object(
$object) && property_exists(
$object,
'element')) ?
', object element='.$object->element :
''), LOG_DEBUG);
336 $parameters[
'currentcontext'] =
$context;
338 if ($hooktype ==
'addreplace') {
340 $resactiontmp = (int) $actionclassinstance->$method($parameters,
$object, $action, $this);
341 $resaction += $resactiontmp;
343 if ($resactiontmp < 0 || !empty($actionclassinstance->error) || (!empty($actionclassinstance->errors) && count($actionclassinstance->errors) > 0)) {
345 $this->error = $actionclassinstance->error;
346 $this->errors = array_merge($this->errors, (array) $actionclassinstance->errors);
347 dol_syslog(
"Error on hook module=".
$module.
", method ".$method.
", class ".get_class($actionclassinstance).
", hooktype=".$hooktype.(empty($this->error) ?
'' :
" ".$this->error).(empty($this->errors) ?
'' :
" ".implode(
",", $this->errors)), LOG_ERR);
350 if (!empty($actionclassinstance->warnings) && count($actionclassinstance->warnings) > 0) {
351 $this->warnings = array_merge($this->warnings, (array) $actionclassinstance->warnings);
352 dol_syslog(
"Warning on hook module=".
$module.
", method ".$method.
", class ".get_class($actionclassinstance).
", hooktype=".$hooktype.(empty($this->warnings) ?
'' :
" ".implode(
",", $this->warnings)), LOG_DEBUG);
355 if (isset($actionclassinstance->results) && is_array($actionclassinstance->results)) {
356 if ($resactiontmp > 0) {
357 $localResArray = $actionclassinstance->results;
359 $localResArray = array_merge_recursive($localResArray, $actionclassinstance->results);
363 if (!empty($actionclassinstance->resprints)) {
364 if ($resactiontmp > 0) {
365 $localResPrint = (string) $actionclassinstance->resprints;
367 $localResPrint .= (string) $actionclassinstance->resprints;
374 if (is_array($parameters) && !empty($parameters[
'special_code']) && $parameters[
'special_code'] > 3 && (property_exists($actionclassinstance,
'module_number') && ($parameters[
'special_code'] != $actionclassinstance->module_number))) {
379 dol_syslog(
"Call method ".$method.
" of class ".get_class($actionclassinstance).
", module=".
$module.
", hooktype=".$hooktype, LOG_DEBUG);
383 $resactiontmp = $actionclassinstance->$method($parameters,
$object, $action, $this);
384 $resaction += $resactiontmp;
386 if (!empty($actionclassinstance->results) && is_array($actionclassinstance->results)) {
387 $localResArray = array_merge_recursive($localResArray, $actionclassinstance->results);
389 if (!empty($actionclassinstance->resprints)) {
390 $localResPrint .= (string) $actionclassinstance->resprints;
392 if (is_numeric($resactiontmp) && $resactiontmp < 0) {
394 $this->error = $actionclassinstance->error;
395 $this->errors = array_merge($this->errors, (array) $actionclassinstance->errors);
396 dol_syslog(
"Error on hook module=".
$module.
", method ".$method.
", class ".get_class($actionclassinstance).
", hooktype=".$hooktype.(empty($this->error) ?
'' :
" ".$this->error).(empty($this->errors) ?
'' :
" ".implode(
",", $this->errors)), LOG_ERR);
400 if (!is_array($resactiontmp) && !is_numeric($resactiontmp)) {
401 dol_syslog(
'Error: Bug into hook '.$method.
' of module class '.get_class($actionclassinstance).
'. Method must not return a string but an int (0=OK, 1=Replace, -1=KO) and set string into ->resprints', LOG_ERR);
402 if (empty($actionclassinstance->resprints)) {
403 $localResPrint .= $resactiontmp;
410 $actionclassinstance->results = array();
411 $actionclassinstance->resprints =
null;
416 $this->resPrint = $localResPrint;
417 $this->resArray = $localResArray;
419 return ($error ? -1 : $resaction);