28require_once DOL_DOCUMENT_ROOT.
'/core/triggers/dolibarrtriggers.class.php';
49 public $lastmoduleerror;
54 public $errors = array();
84 dol_syslog(get_class($this).
"::run_triggers action=".$action.
" Launch run_triggers", LOG_DEBUG);
88 if (!is_object(
$object) || !($conf instanceof
Conf)) {
89 $error =
'function run_triggers called with wrong parameters object or conf. action='.$action.
' object='.((string) (
int) is_object(
$object)).
' user='.((
string) (int) is_object($user)).
' langs='.((
string) (int) is_object($langs)).
' conf='.((
string) (int) is_object($conf));
90 dol_syslog(get_class($this).
'::run_triggers '.$error, LOG_ERR);
91 $this->errors[] = $error;
95 dol_syslog(get_class($this).
'::run_triggers was called with wrong parameters langs. action='.$action.
' object='.((
string) (
int) is_object(
$object)).
' user='.((
string) (
int) is_object($user)).
' langs='.((
string) (
int) is_object($langs)).
' conf=1', LOG_WARNING);
98 if (!($user instanceof
User)) {
99 dol_syslog(get_class($this).
'::run_triggers was called with wrong parameters user. action='.$action.
' object='.((
string) (
int) is_object(
$object)).
' user='.((
string) (
int) is_object($user)).
' langs=1 conf=1', LOG_WARNING);
100 $user =
new User($this->db);
103 $nbfile = $nbtotal = $nbok = $nbko = 0;
104 $this->lastmoduleerror =
'';
116 && in_array(
$mysoc->country_code, array(
'FR')) &&
$mysoc->tva_assuj
121 $langs->load(
"errors");
122 $error =
'You try to validate an invoice in the following situation:<br>';
123 $error .=
'Your country: '.$mysoc->country_code.
'<br>';
124 $error .=
'Your are using VAT: '.yn(
$mysoc->tva_assuj).
'<br>';
126 $error .=
'The invoice is intended for a thirdparty with type : individual<br>';
127 $error .=
'Customer VAT number = '.$object->thirdparty->tva_intra.
'<br>';
128 $error .=
'Customer Id prof = '.$object->thirdparty->idprof1.
' '.
$object->thirdparty->idprof2.
' '.
$object->thirdparty->idprof3.
' '.
$object->thirdparty->idprof4.
' '.
$object->thirdparty->idprof5.
' '.
$object->thirdparty->idprof6.
'<br>';
129 $error .=
'Customer Business entity type = '.$object->thirdparty->typent_code.
'<br>';
131 $error .=
'This means you are eligible the to the French Loi Finance 2025 and need to enable the module Unalterable Archives to be allowed to use a software to record payments.<br>';
132 $error .=
'Please enable the module Unalterable Archives first...';
133 dol_syslog(get_class($this).
'::run_triggers '.$error, LOG_ERR);
134 $this->errors[] = $error;
139 $dirtriggers = array_merge(array(
'/core/triggers'), $conf->modules_parts[
'triggers']);
140 foreach ($dirtriggers as $reldir) {
146 if (!is_dir($newdir)) {
150 $handle = opendir($newdir);
151 if (is_resource($handle)) {
152 $fullpathfiles = array();
153 '@phan-var-force array<string,string> $fullpathfiles';
154 while (($file = readdir($handle)) !==
false) {
156 if (is_readable($newdir.
"/".$file) && preg_match(
'/^interface_([0-9]+)_([^_]+)_(.+)\.class\.php$/i', $file, $reg)) {
164 if (preg_match(
'/NORUN$/i', $file)) {
169 if (strtolower($reg[2]) !=
'all') {
170 $module = preg_replace(
'/^mod/i',
'', $reg[2]);
181 $modName =
"Interface".ucfirst($reg[3]);
183 if (array_key_exists($modName, $fullpathfiles)) {
184 $langs->load(
"errors");
185 dol_syslog(get_class($this).
"::run_triggers action=".$action.
" ".$langs->trans(
"ErrorDuplicateTrigger", $newdir.
"/".$file, $fullpathfiles[$modName]), LOG_WARNING);
191 include_once $newdir.
'/'.$file;
194 dol_syslog(
'ko for '.$modName.
" ".$e->getMessage().
"\n", LOG_ERR);
197 $modules[$i] = $modName;
199 $fullpathfiles[$modName] = $newdir.
'/'.$file;
200 $orders[$i] = $part1.
'_'.$part2.
'_'.$part3;
210 asort($orders, SORT_NATURAL);
213 foreach ($orders as $key => $value) {
214 $modName = $modules[$key];
215 if (empty($modName)) {
218 if (!class_exists($modName)) {
219 dol_syslog(get_class($this).
"::run_triggers action=".$action.
" A trigger file was found with a name interfaces_*_*_".preg_replace(
'/^interface/',
'', strtolower($modName)).
".class.php, but the class ".$modName.
" seems to not exists even after the include of this interface file. Surely a bug in the trigger file or in its name.", LOG_ERR);
223 $objMod =
new $modName($this->db);
224 '@phan-var-force DolibarrTriggers $objMod';
226 $dblevelbefore = $this->db->transaction_opened;
230 if (method_exists($objMod,
'runTrigger')) {
232 $result = $objMod->runTrigger($action,
$object, $user, $langs, $conf);
234 dol_syslog(get_class($this).
"::run_triggers action=".$action.
" A trigger was declared for class ".get_class($objMod).
" but method runTrigger was not found", LOG_ERR);
237 $dblevelafter = $this->db->transaction_opened;
239 if ($dblevelbefore != $dblevelafter) {
240 $errormessage =
"Error, the balance begin/close of db transactions has been broken into trigger ".$modName.
" with action=".$action.
" before=".$dblevelbefore.
" after=".$dblevelafter;
241 $this->errors[] = $errormessage;
260 $this->lastmoduleerror = $modName;
261 if (!empty($objMod->errors)) {
262 $this->errors = array_merge($this->errors, $objMod->errors);
263 } elseif (!empty($objMod->error)) {
264 $this->errors[] = $objMod->error;
269 dol_syslog(get_class($this).
"::run_triggers action=".$action.
" Failed to instantiate trigger for file '".$files[$key].
"'", LOG_ERR);
274 dol_syslog(get_class($this).
"::run_triggers action=".$action.
" Files found: ".$nbfile.
", Files launched: ".$nbtotal.
", Done: ".$nbok.
", Failed: ".$nbko.($this->lastmoduleerror ?
" - Last module in error: ".$this->lastmoduleerror :
"").
" - Nb of error string returned in this->errors = ".count($this->errors), LOG_ERR);
291 global $conf, $langs, $db;
296 $iscoreorexternal = array();
301 $dirtriggers = array_merge(array(
'/core/triggers/'), $conf->modules_parts[
'triggers']);
302 if (is_array($forcedirtriggers)) {
303 $dirtriggers = $forcedirtriggers;
306 foreach ($dirtriggers as $reldir) {
311 if (!is_dir($newdir)) {
315 $handle = opendir($newdir);
316 if (is_resource($handle)) {
317 while (($file = readdir($handle)) !==
false) {
319 if (is_readable($newdir.
'/'.$file) && preg_match(
'/^interface_([0-9]+)_([^_]+)_(.+)\.class\.php/', $file, $reg)) {
320 if (preg_match(
'/\.back$/', $file)) {
328 $modName =
'Interface'.ucfirst($reg[3]);
330 if (in_array($modName, $modules)) {
331 $langs->load(
"errors");
332 print
'<div class="error">'.$langs->trans(
"Error").
' : '.$langs->trans(
"ErrorDuplicateTrigger", $modName,
"/htdocs/core/triggers/").
'</div>';
334 include_once $newdir.
'/'.$file;
338 $fullpath[$i] = $dir.
'/'.$file;
339 $relpath[$i] = preg_replace(
'/^\//',
'', $reldir).
'/'.$file;
340 $iscoreorexternal[$i] = ($reldir ==
'/core/triggers/' ?
'internal' :
'external');
341 $modules[$i] = $modName;
342 $orders[$i] = $part1.
'_'.$part2.
'_'.$part3;
351 asort($orders, SORT_NATURAL);
357 foreach ($orders as $key => $value) {
358 $modName = $modules[$key];
359 if (empty($modName)) {
363 if (!class_exists($modName)) {
364 print
'Error: A trigger file was found but its class "'.$modName.
'" was not found.'.
"<br>\n";
371 $objMod =
new $modName($db);
372 '@phan-var-force DolibarrTriggers $objMod';
374 if (is_subclass_of($objMod,
'DolibarrTriggers')) {
377 $disabledbymodule = 1;
381 if (preg_match(
'/NORUN$/i', $files[$key])) {
385 if (preg_match(
'/^interface_([0-9]+)_([^_]+)_(.+)\.class\.php/i', $files[$key], $reg)) {
386 $module = preg_replace(
'/^mod/i',
'', $reg[2]);
387 if (strtolower($module) ==
'all') {
388 $disabledbymodule = 0;
390 $disabledbymodule = 2;
392 $triggers[$j][
'module'] = strtolower($module);
396 $triggers[$j][
'picto'] = (!empty($objMod->picto)) ?
img_object(
'', $objMod->picto,
'class="valignmiddle pictomodule pictofixedwidth"') :
img_object(
'',
'generic',
'class="valignmiddle pictomodule pictofixedwidth"');
397 $triggers[$j][
'file'] = $files[$key];
398 $triggers[$j][
'fullpath'] = $fullpath[$key];
399 $triggers[$j][
'relpath'] = $relpath[$key];
400 $triggers[$j][
'iscoreorexternal'] = $iscoreorexternal[$key];
401 $triggers[$j][
'version'] = $objMod->getVersion();
402 $triggers[$j][
'status'] =
img_picto($langs->trans(
"Active"),
'tick');
403 if ($disabledbyname > 0 || $disabledbymodule > 1) {
404 $triggers[$j][
'status'] =
'';
407 $text =
'<b>'.$langs->trans(
"Description").
':</b><br>';
408 $text .= $objMod->getDesc().
'<br>';
409 $text .=
'<br><b>'.$langs->trans(
"Status").
':</b><br>';
410 if ($disabledbyname == 1) {
411 $text .= $langs->trans(
"TriggerDisabledByName").
'<br>';
412 if ($disabledbymodule == 2) {
413 $text .= $langs->trans(
"TriggerDisabledAsModuleDisabled", $module).
'<br>';
416 if ($disabledbymodule == 0) {
417 $text .= $langs->trans(
"TriggerAlwaysActive").
'<br>';
419 if ($disabledbymodule == 1) {
420 $text .= $langs->trans(
"TriggerActiveAsModuleActive", $module).
'<br>';
422 if ($disabledbymodule == 2) {
423 $text .= $langs->trans(
"TriggerDisabledAsModuleDisabled", $module).
'<br>';
427 $triggers[$j][
'picto'] = (!empty($objMod->picto)) ?
img_object(
'', $objMod->picto,
'class="valignmiddle pictomodule "') :
img_object(
'',
'generic',
'class="valignmiddle pictomodule "');
428 $triggers[$j][
'file'] = $files[$key];
429 $triggers[$j][
'fullpath'] = $fullpath[$key];
430 $triggers[$j][
'relpath'] = $relpath[$key];
431 $triggers[$j][
'status'] =
img_picto(
'Error: Trigger '.$modName.
' does not extends DolibarrTriggers',
'warning');
434 $text =
'Error: Trigger '.$modName.
' does not extend DolibarrTriggers';
437 print $e->getMessage();
440 $triggers[$j][
'info'] = $text;
if(! $sortfield) if(! $sortorder) $object
Class to stock current configuration.
Class to manage invoices.
Class to manage triggers.
__construct($db)
Constructor.
run_triggers($action, $object, $user, $langs, $conf)
Function called when a Dolibarr business event occurs This function call all qualified triggers.
getTriggersList($forcedirtriggers=null)
Return list of triggers.
Class to manage third parties objects (customers, suppliers, prospects...)
isACompany()
Check if third party is a company (Business) or an end user (Consumer)
Class to manage translations.
Class to manage Dolibarr users.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.