112 if (!is_array(
$conf->modules_parts[
'hooks']) || empty(
$conf->modules_parts[
'hooks'])) {
117 if (!is_array($arraycontext)) {
118 $arraycontext = array($arraycontext);
121 $this->contextarray = array_unique(array_merge($arraycontext, $this->contextarray));
123 $foundcontextmodule =
false;
126 foreach (
$conf->modules_parts[
'hooks'] as $module =>
$hooks) {
127 if (!isModEnabled($module)) {
132 foreach ($arraycontext as
$context) {
136 $arrayhooks = explode(
':',
$hooks);
139 if (!in_array(
$context, $arrayhooks) && !in_array(
'all', $arrayhooks)) {
146 if (empty($this->hooks[
$context][$module]) || !is_object($this->hooks[
$context][$module])) {
147 $path =
'/'.$module.
'/class/';
148 $actionfile =
'actions_'.$module.
'.class.php';
152 $controlclassname =
'Actions'.ucfirst($module);
154 $actionInstance =
new $controlclassname($this->db);
155 '@phan-var-force CommonHookActions $actionInstance';
158 $priority = (!property_exists($actionInstance,
'priority') || empty($actionInstance->priority)) ? 50 : $actionInstance->priority;
160 $this->hooks[
$context][$module] = $actionInstance;
161 $this->hooksSorted[
$context][$priority.
':'.$module] = $actionInstance;
163 $foundcontextmodule =
true;
166 $stringtolog =
'context='.$context.
'-path='.$path.$actionfile.
'-priority='.$priority;
167 dol_syslog(get_class($this).
"::initHooks Loading hooks: ".$stringtolog, LOG_DEBUG);
169 dol_syslog(get_class($this).
"::initHooks Failed to load hook in ".$path.$actionfile, LOG_WARNING);
178 if ($foundcontextmodule) {
179 foreach ($arraycontext as
$context) {
180 if (!empty($this->hooksSorted[
$context])) {
181 ksort($this->hooksSorted[
$context], SORT_NATURAL);
203 if (isModEnabled(
'debugbar') && function_exists(
'debug_backtrace')) {
204 $trace = debug_backtrace();
205 if (isset($trace[0])) {
206 $hookInformations = [
208 'contexts' => $this->contextarray,
209 'file' => $trace[0][
'file'],
210 'line' => $trace[0][
'line'],
213 $hash = md5(json_encode($hookInformations));
214 if (!empty($this->hooksHistory[$hash])) {
215 $this->hooksHistory[$hash][
'count']++;
217 $hookInformations[
'count'] = 1;
218 $this->hooksHistory[$hash] = $hookInformations;
223 if (!is_array($this->hooks) || empty($this->hooks)) {
226 if (!is_array($parameters)) {
227 dol_syslog(
'executeHooks was called with a non array $parameters. Surely a bug.', LOG_WARNING);
228 $parameters = array();
231 $parameters[
'context'] = implode(
':', $this->contextarray);
235 $hooktype =
'addreplace';
237 if (in_array($method, array(
239 'dashboardAccountancy',
240 'dashboardActivities',
241 'dashboardCommercials',
242 'dashboardContracts',
244 'dashboardEmailings',
245 'dashboardExpenseReport',
247 'dashboardInterventions',
250 'dashboardOpensurvey',
252 'dashboardOrdersSuppliers',
253 'dashboardProductServices',
256 'dashboardSpecialBills',
257 'dashboardSupplierProposal',
258 'dashboardThirdparties',
260 'dashboardUsersGroups',
261 'dashboardWarehouse',
262 'dashboardWarehouseReceptions',
263 'dashboardWarehouseSendings',
268 'formBuilddocOptions',
271 $hooktype =
'output';
276 $localResArray = array();
278 $this->resNbOfHooks = 0;
282 $modulealreadyexecuted = array();
285 foreach ($this->hooksSorted as
$context => $modules) {
286 if (!empty($modules)) {
287 '@phan-var-force array<string,CommonHookActions> $modules';
289 foreach ($modules as $module => $actionclassinstance) {
290 $module = preg_replace(
'/^\d+:/',
'', $module);
294 if (in_array($module, $modulealreadyexecuted)) {
299 if (!method_exists($actionclassinstance, $method)) {
303 $this->resNbOfHooks++;
305 $modulealreadyexecuted[$module] = $module;
308 $actionclassinstance->error =
'';
309 $actionclassinstance->errors = array();
313 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);
318 $parameters[
'currentcontext'] =
$context;
320 if ($hooktype ==
'addreplace') {
322 $resactiontmp = (int) $actionclassinstance->$method($parameters,
$object, $action, $this);
323 $resaction += $resactiontmp;
325 if ($resactiontmp < 0 || !empty($actionclassinstance->error) || (!empty($actionclassinstance->errors) && count($actionclassinstance->errors) > 0)) {
327 $this->error = $actionclassinstance->error;
328 $this->errors = array_merge($this->errors, (array) $actionclassinstance->errors);
329 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);
332 if (isset($actionclassinstance->results) && is_array($actionclassinstance->results)) {
333 if ($resactiontmp > 0) {
334 $localResArray = $actionclassinstance->results;
336 $localResArray = array_merge_recursive($localResArray, $actionclassinstance->results);
340 if (!empty($actionclassinstance->resprints)) {
341 if ($resactiontmp > 0) {
342 $localResPrint = (string) $actionclassinstance->resprints;
344 $localResPrint .= (string) $actionclassinstance->resprints;
351 if (is_array($parameters) && !empty($parameters[
'special_code']) && $parameters[
'special_code'] > 3 && (property_exists($actionclassinstance,
'module_number') && ($parameters[
'special_code'] != $actionclassinstance->module_number))) {
356 dol_syslog(
"Call method ".$method.
" of class ".get_class($actionclassinstance).
", module=".$module.
", hooktype=".$hooktype, LOG_DEBUG);
360 $resactiontmp = $actionclassinstance->$method($parameters,
$object, $action, $this);
361 $resaction += $resactiontmp;
363 if (!empty($actionclassinstance->results) && is_array($actionclassinstance->results)) {
364 $localResArray = array_merge_recursive($localResArray, $actionclassinstance->results);
366 if (!empty($actionclassinstance->resprints)) {
367 $localResPrint .= (string) $actionclassinstance->resprints;
369 if (is_numeric($resactiontmp) && $resactiontmp < 0) {
371 $this->error = $actionclassinstance->error;
372 $this->errors = array_merge($this->errors, (array) $actionclassinstance->errors);
373 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);
377 if (!is_array($resactiontmp) && !is_numeric($resactiontmp)) {
378 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);
379 if (empty($actionclassinstance->resprints)) {
380 $localResPrint .= $resactiontmp;
387 $actionclassinstance->results = array();
388 $actionclassinstance->resprints =
null;
393 $this->resPrint = $localResPrint;
394 $this->resArray = $localResArray;
396 return ($error ? -1 : $resaction);