111 if (!is_array(
$conf->modules_parts[
'hooks']) || empty(
$conf->modules_parts[
'hooks'])) {
116 if (!is_array($arraycontext)) {
117 $arraycontext = array($arraycontext);
120 $this->contextarray = array_unique(array_merge($arraycontext, $this->contextarray));
122 $foundcontextmodule =
false;
125 foreach (
$conf->modules_parts[
'hooks'] as $module =>
$hooks) {
126 if (!isModEnabled($module)) {
131 foreach ($arraycontext as
$context) {
135 $arrayhooks = explode(
':',
$hooks);
138 if (in_array(
$context, $arrayhooks) || in_array(
'all', $arrayhooks)) {
140 if (empty($this->hooks[
$context][$module]) || !is_object($this->hooks[
$context][$module])) {
141 $path =
'/'.$module.
'/class/';
142 $actionfile =
'actions_'.$module.
'.class.php';
146 $controlclassname =
'Actions'.ucfirst($module);
148 $actionInstance =
new $controlclassname($this->db);
149 '@phan-var-force CommonHookActions $actionInstance';
152 $priority = empty($actionInstance->priority) ? 50 : $actionInstance->priority;
154 $this->hooks[
$context][$module] = $actionInstance;
155 $this->hooksSorted[
$context][$priority.
':'.$module] = $actionInstance;
157 $foundcontextmodule =
true;
160 $stringtolog =
'context='.$context.
'-path='.$path.$actionfile.
'-priority='.$priority;
161 dol_syslog(get_class($this).
"::initHooks Loading hooks: ".$stringtolog, LOG_DEBUG);
163 dol_syslog(get_class($this).
"::initHooks Failed to load hook in ".$path.$actionfile, LOG_WARNING);
175 if ($foundcontextmodule) {
176 foreach ($arraycontext as
$context) {
177 if (!empty($this->hooksSorted[
$context])) {
178 ksort($this->hooksSorted[
$context], SORT_NATURAL);
200 if (isModEnabled(
'debugbar') && function_exists(
'debug_backtrace')) {
201 $trace = debug_backtrace();
202 if (isset($trace[0])) {
203 $hookInformations = [
205 'contexts' => $this->contextarray,
206 'file' => $trace[0][
'file'],
207 'line' => $trace[0][
'line'],
210 $hash = md5(json_encode($hookInformations));
211 if (!empty($this->hooksHistory[$hash])) {
212 $this->hooksHistory[$hash][
'count']++;
214 $hookInformations[
'count'] = 1;
215 $this->hooksHistory[$hash] = $hookInformations;
220 if (!is_array($this->hooks) || empty($this->hooks)) {
223 if (!is_array($parameters)) {
224 dol_syslog(
'executeHooks was called with a non array $parameters. Surely a bug.', LOG_WARNING);
225 $parameters = array();
228 $parameters[
'context'] = implode(
':', $this->contextarray);
232 $hooktype =
'addreplace';
234 if (in_array($method, array(
236 'dashboardAccountancy',
237 'dashboardActivities',
238 'dashboardCommercials',
239 'dashboardContracts',
241 'dashboardEmailings',
242 'dashboardExpenseReport',
244 'dashboardInterventions',
247 'dashboardOpensurvey',
249 'dashboardOrdersSuppliers',
250 'dashboardProductServices',
253 'dashboardSpecialBills',
254 'dashboardSupplierProposal',
255 'dashboardThirdparties',
257 'dashboardUsersGroups',
258 'dashboardWarehouse',
259 'dashboardWarehouseReceptions',
260 'dashboardWarehouseSendings',
265 'formBuilddocOptions',
268 $hooktype =
'output';
273 $localResArray = array();
275 $this->resNbOfHooks = 0;
279 $modulealreadyexecuted = array();
282 foreach ($this->hooksSorted as
$context => $modules) {
283 if (!empty($modules)) {
284 '@phan-var-force array<string,CommonHookActions> $modules';
286 foreach ($modules as $module => $actionclassinstance) {
287 $module = preg_replace(
'/^\d+:/',
'', $module);
291 if (in_array($module, $modulealreadyexecuted)) {
296 if (!method_exists($actionclassinstance, $method)) {
300 $this->resNbOfHooks++;
302 $modulealreadyexecuted[$module] = $module;
305 $actionclassinstance->error =
'';
306 $actionclassinstance->errors = array();
310 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);
315 $parameters[
'currentcontext'] =
$context;
317 if ($hooktype ==
'addreplace') {
319 $resactiontmp = (int) $actionclassinstance->$method($parameters,
$object, $action, $this);
320 $resaction += $resactiontmp;
322 if ($resactiontmp < 0 || !empty($actionclassinstance->error) || (!empty($actionclassinstance->errors) && count($actionclassinstance->errors) > 0)) {
324 $this->error = $actionclassinstance->error;
325 $this->errors = array_merge($this->errors, (array) $actionclassinstance->errors);
326 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);
329 if (isset($actionclassinstance->results) && is_array($actionclassinstance->results)) {
330 if ($resactiontmp > 0) {
331 $localResArray = $actionclassinstance->results;
333 $localResArray = array_merge_recursive($localResArray, $actionclassinstance->results);
337 if (!empty($actionclassinstance->resprints)) {
338 if ($resactiontmp > 0) {
339 $localResPrint = (string) $actionclassinstance->resprints;
341 $localResPrint .= (string) $actionclassinstance->resprints;
348 if (is_array($parameters) && !empty($parameters[
'special_code']) && $parameters[
'special_code'] > 3 && $parameters[
'special_code'] != $actionclassinstance->module_number) {
353 dol_syslog(
"Call method ".$method.
" of class ".get_class($actionclassinstance).
", module=".$module.
", hooktype=".$hooktype, LOG_DEBUG);
357 $resactiontmp = $actionclassinstance->$method($parameters,
$object, $action, $this);
358 $resaction += $resactiontmp;
360 if (!empty($actionclassinstance->results) && is_array($actionclassinstance->results)) {
361 $localResArray = array_merge_recursive($localResArray, $actionclassinstance->results);
363 if (!empty($actionclassinstance->resprints)) {
364 $localResPrint .= (string) $actionclassinstance->resprints;
366 if (is_numeric($resactiontmp) && $resactiontmp < 0) {
368 $this->error = $actionclassinstance->error;
369 $this->errors = array_merge($this->errors, (array) $actionclassinstance->errors);
370 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);
374 if (!is_array($resactiontmp) && !is_numeric($resactiontmp)) {
375 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);
376 if (empty($actionclassinstance->resprints)) {
377 $localResPrint .= $resactiontmp;
384 $actionclassinstance->results = array();
385 $actionclassinstance->resprints =
null;
390 $this->resPrint = $localResPrint;
391 $this->resArray = $localResArray;
393 return ($error ? -1 : $resaction);