118 if (!is_array(
$conf->modules_parts[
'hooks']) || empty(
$conf->modules_parts[
'hooks'])) {
123 if (!is_array($arraycontext)) {
124 $arraycontext = array($arraycontext);
127 $this->contextarray = array_unique(array_merge($arraycontext, $this->contextarray));
129 $foundcontextmodule =
false;
132 foreach (
$conf->modules_parts[
'hooks'] as $module =>
$hooks) {
138 foreach ($arraycontext as
$context) {
142 $arrayhooks = explode(
':',
$hooks);
145 if (!in_array(
$context, $arrayhooks) && !in_array(
'all', $arrayhooks)) {
152 if (empty($this->hooks[
$context][$module]) || !is_object($this->hooks[
$context][$module])) {
153 $path =
'/'.$module.
'/class/';
154 $actionfile =
'actions_'.$module.
'.class.php';
158 $controlclassname =
'Actions'.ucfirst($module);
160 $actionInstance =
new $controlclassname($this->db);
161 '@phan-var-force CommonHookActions $actionInstance';
164 $priority = (!property_exists($actionInstance,
'priority') || empty($actionInstance->priority)) ? 50 : $actionInstance->priority;
166 $this->hooks[
$context][$module] = $actionInstance;
167 $this->hooksSorted[
$context][$priority.
':'.$module] = $actionInstance;
169 $foundcontextmodule =
true;
172 $stringtolog =
'context='.$context.
'-path='.$path.$actionfile.
'-priority='.$priority;
173 dol_syslog(get_class($this).
"::initHooks Loading hooks: ".$stringtolog, LOG_DEBUG);
175 dol_syslog(get_class($this).
"::initHooks Failed to load hook in ".$path.$actionfile, LOG_WARNING);
184 if ($foundcontextmodule) {
185 foreach ($arraycontext as
$context) {
186 if (!empty($this->hooksSorted[
$context])) {
187 ksort($this->hooksSorted[
$context], SORT_NATURAL);
213 if (
isModEnabled(
'debugbar') && function_exists(
'debug_backtrace')) {
214 $trace = debug_backtrace();
215 if (isset($trace[0])) {
216 $hookInformations = [
218 'contexts' => $this->contextarray,
219 'file' => $trace[0][
'file'],
220 'line' => $trace[0][
'line'],
223 $hash = md5(json_encode($hookInformations));
224 if (!empty($this->hooksHistory[$hash])) {
225 $this->hooksHistory[$hash][
'count']++;
227 $hookInformations[
'count'] = 1;
228 $this->hooksHistory[$hash] = $hookInformations;
233 if (!is_array($this->hooks) || empty($this->hooks)) {
236 if (!is_array($parameters)) {
237 dol_syslog(
'executeHooks was called with a non array $parameters. Surely a bug.', LOG_WARNING);
238 $parameters = array();
241 $parameters[
'context'] = implode(
':', $this->contextarray);
245 $hooktype =
'addreplace';
247 if (in_array($method, array(
249 'dashboardAccountancy',
250 'dashboardActivities',
251 'dashboardCommercials',
252 'dashboardContracts',
254 'dashboardEmailings',
255 'dashboardExpenseReport',
257 'dashboardInterventions',
260 'dashboardOpensurvey',
262 'dashboardOrdersSuppliers',
263 'dashboardProductServices',
266 'dashboardSpecialBills',
267 'dashboardSupplierProposal',
268 'dashboardThirdparties',
270 'dashboardUsersGroups',
271 'dashboardWarehouse',
272 'dashboardWarehouseReceptions',
273 'dashboardWarehouseSendings',
278 'formBuilddocOptions',
281 $hooktype =
'output';
286 $localResArray = array();
288 $this->resNbOfHooks = 0;
292 $modulealreadyexecuted = array();
295 foreach ($this->hooksSorted as
$context => $modules) {
296 if (!empty($modules)) {
297 '@phan-var-force array<string,CommonHookActions> $modules';
299 foreach ($modules as $module => $actionclassinstance) {
300 $module = preg_replace(
'/^\d+:/',
'', $module);
304 if (in_array($module, $modulealreadyexecuted)) {
309 if (!method_exists($actionclassinstance, $method)) {
313 $this->resNbOfHooks++;
315 $modulealreadyexecuted[$module] = $module;
318 $actionclassinstance->error =
'';
319 $actionclassinstance->errors = array();
320 $actionclassinstance->warnings = array();
324 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);
329 $parameters[
'currentcontext'] =
$context;
331 if ($hooktype ==
'addreplace') {
333 $resactiontmp = (int) $actionclassinstance->$method($parameters,
$object, $action, $this);
334 $resaction += $resactiontmp;
336 if ($resactiontmp < 0 || !empty($actionclassinstance->error) || (!empty($actionclassinstance->errors) && count($actionclassinstance->errors) > 0)) {
338 $this->error = $actionclassinstance->error;
339 $this->errors = array_merge($this->errors, (array) $actionclassinstance->errors);
340 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);
343 if (!empty($actionclassinstance->warnings) && count($actionclassinstance->warnings) > 0) {
344 $this->warnings = array_merge($this->warnings, (array) $actionclassinstance->warnings);
345 dol_syslog(
"Warning on hook module=".$module.
", method ".$method.
", class ".get_class($actionclassinstance).
", hooktype=".$hooktype.(empty($this->warnings) ?
'' :
" ".implode(
",", $this->warnings)), LOG_DEBUG);
348 if (isset($actionclassinstance->results) && is_array($actionclassinstance->results)) {
349 if ($resactiontmp > 0) {
350 $localResArray = $actionclassinstance->results;
352 $localResArray = array_merge_recursive($localResArray, $actionclassinstance->results);
356 if (!empty($actionclassinstance->resprints)) {
357 if ($resactiontmp > 0) {
358 $localResPrint = (
string) $actionclassinstance->resprints;
360 $localResPrint .= (
string) $actionclassinstance->resprints;
367 if (is_array($parameters) && !empty($parameters[
'special_code']) && $parameters[
'special_code'] > 3 && (property_exists($actionclassinstance,
'module_number') && ($parameters[
'special_code'] != $actionclassinstance->module_number))) {
372 dol_syslog(
"Call method ".$method.
" of class ".get_class($actionclassinstance).
", module=".$module.
", hooktype=".$hooktype, LOG_DEBUG);
376 $resactiontmp = $actionclassinstance->$method($parameters,
$object, $action, $this);
377 $resaction += $resactiontmp;
379 if (!empty($actionclassinstance->results) && is_array($actionclassinstance->results)) {
380 $localResArray = array_merge_recursive($localResArray, $actionclassinstance->results);
382 if (!empty($actionclassinstance->resprints)) {
383 $localResPrint .= (
string) $actionclassinstance->resprints;
385 if (is_numeric($resactiontmp) && $resactiontmp < 0) {
387 $this->error = $actionclassinstance->error;
388 $this->errors = array_merge($this->errors, (array) $actionclassinstance->errors);
389 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);
393 if (!is_array($resactiontmp) && !is_numeric($resactiontmp)) {
394 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);
395 if (empty($actionclassinstance->resprints)) {
396 $localResPrint .= $resactiontmp;
403 $actionclassinstance->results = array();
404 $actionclassinstance->resprints =
null;
409 $this->resPrint = $localResPrint;
410 $this->resArray = $localResArray;
412 return ($error ? -1 : $resaction);