2005-04-21 20:49:15 +02:00
< ? php
2009-01-21 15:09:42 +01:00
/* Copyright ( C ) 2005 - 2009 Laurent Destailleur < eldy @ users . sourceforge . net >
2007-10-13 01:48:20 +02:00
* Copyright ( C ) 2006 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
2018-10-27 14:43:12 +02:00
* Copyright ( C ) 2010 Regis Houssin < regis . houssin @ inodbox . com >
2005-04-21 20:49:15 +02:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2013-01-16 15:36:08 +01:00
* the Free Software Foundation ; either version 3 of the License , or
2005-04-21 20:49:15 +02:00
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2011-08-01 01:45:11 +02:00
* along with this program . If not , see < http :// www . gnu . org / licenses />.
2005-04-21 20:49:15 +02:00
*/
/**
2010-11-22 10:18:53 +01:00
* \file htdocs / core / class / interfaces . class . php
* \ingroup core
2010-04-02 11:59:18 +02:00
* \brief Fichier de la classe de gestion des triggers
*/
2005-04-21 20:49:15 +02:00
2014-10-11 18:27:30 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/triggers/dolibarrtriggers.class.php' ;
2005-04-21 20:49:15 +02:00
/**
2012-01-27 16:10:44 +01:00
* Class to manage triggers
2010-04-02 11:59:18 +02:00
*/
2010-04-22 00:14:11 +02:00
class Interfaces
2005-04-21 20:49:15 +02:00
{
2018-08-22 11:06:34 +02:00
/**
* @ var DoliDB Database handler .
*/
public $db ;
2018-09-02 23:44:53 +02:00
2019-02-26 23:15:28 +01:00
public $dir ; // Directory with all core and external triggers files
2018-09-02 23:44:53 +02:00
2018-08-17 19:31:22 +02:00
/**
2019-02-26 23:15:28 +01:00
* @ var string [] Error codes ( or messages )
*/
public $errors = array ();
2011-09-11 20:35:38 +02:00
/**
* Constructor
*
2012-01-11 01:52:00 +01:00
* @ param DoliDB $db Database handler
2011-09-11 20:35:38 +02:00
*/
2019-02-26 23:15:28 +01:00
public function __construct ( $db )
2011-09-11 20:35:38 +02:00
{
2012-01-11 01:52:00 +01:00
$this -> db = $db ;
2011-09-11 20:35:38 +02:00
}
2019-02-26 23:15:28 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2011-09-11 20:35:38 +02:00
/**
2012-01-27 16:10:44 +01:00
* Function called when a Dolibarr business event occurs
* This function call all qualified triggers .
2012-02-19 17:12:17 +01:00
*
2012-01-27 16:10:44 +01:00
* @ param string $action Trigger event code
2015-07-19 15:24:54 +02:00
* @ param object $object Objet concerned . Some context information may also be provided into array property object -> context .
2012-01-27 16:10:44 +01:00
* @ param User $user Objet user
2018-12-27 05:58:27 +01:00
* @ param Translate $langs Objet lang
2012-01-27 16:10:44 +01:00
* @ param Conf $conf Objet conf
* @ return int Nb of triggers ran if no error , - Nb of triggers with errors otherwise .
2011-09-11 20:35:38 +02:00
*/
2019-02-26 23:15:28 +01:00
public function run_triggers ( $action , $object , $user , $langs , $conf )
2011-09-11 20:35:38 +02:00
{
2018-09-02 23:44:53 +02:00
// phpcs:enable
2011-09-11 20:35:38 +02:00
// Check parameters
if ( ! is_object ( $object ) || ! is_object ( $conf )) // Error
{
2019-02-26 23:15:28 +01:00
$this -> error = 'function run_triggers called with wrong parameters action=' . $action . ' object=' . is_object ( $object ) . ' user=' . is_object ( $user ) . ' langs=' . is_object ( $langs ) . ' conf=' . is_object ( $conf );
2014-09-22 20:16:58 +02:00
dol_syslog ( get_class ( $this ) . '::run_triggers ' . $this -> error , LOG_ERR );
2019-02-26 23:15:28 +01:00
$this -> errors [] = $this -> error ;
2011-09-11 20:35:38 +02:00
return - 1 ;
}
2017-02-28 20:55:14 +01:00
if ( ! is_object ( $langs )) // Warning
2011-09-11 20:35:38 +02:00
{
2012-01-27 16:10:44 +01:00
dol_syslog ( get_class ( $this ) . '::run_triggers was called with wrong parameters action=' . $action . ' object=' . is_object ( $object ) . ' user=' . is_object ( $user ) . ' langs=' . is_object ( $langs ) . ' conf=' . is_object ( $conf ), LOG_WARNING );
2011-09-11 20:35:38 +02:00
}
2017-02-28 20:55:14 +01:00
if ( ! is_object ( $user )) // Warning
{
dol_syslog ( get_class ( $this ) . '::run_triggers was called with wrong parameters action=' . $action . ' object=' . is_object ( $object ) . ' user=' . is_object ( $user ) . ' langs=' . is_object ( $langs ) . ' conf=' . is_object ( $conf ), LOG_WARNING );
global $db ;
$user = new User ( $db );
}
2018-12-27 06:04:55 +01:00
//dol_syslog(get_class($this)."::run_triggers action=".$action." Launch run_triggers", LOG_DEBUG);
2017-06-02 20:01:25 +02:00
2012-01-31 20:32:26 +01:00
$nbfile = $nbtotal = $nbok = $nbko = 0 ;
2012-02-19 17:12:17 +01:00
2012-01-31 20:32:26 +01:00
$files = array ();
$modules = array ();
$orders = array ();
2019-02-26 23:15:28 +01:00
$i = 0 ;
2017-06-02 20:01:25 +02:00
2018-12-27 05:58:27 +01:00
2019-02-26 23:15:28 +01:00
$dirtriggers = array_merge ( array ( '/core/triggers' ), $conf -> modules_parts [ 'triggers' ]);
2012-02-19 17:12:17 +01:00
foreach ( $dirtriggers as $reldir )
2011-09-11 20:35:38 +02:00
{
2019-01-27 11:55:16 +01:00
$dir = dol_buildpath ( $reldir , 0 );
2012-02-22 16:18:03 +01:00
$newdir = dol_osencode ( $dir );
2011-09-11 20:35:38 +02:00
//print "xx".$dir;exit;
2012-02-22 16:18:03 +01:00
// Check if directory exists (we do not use dol_is_dir to avoir loading files.lib.php at each call)
if ( ! is_dir ( $newdir )) continue ;
2011-09-11 20:35:38 +02:00
2012-02-22 16:18:03 +01:00
$handle = opendir ( $newdir );
2010-12-15 19:15:08 +01:00
if ( is_resource ( $handle ))
{
2011-09-11 20:35:38 +02:00
while (( $file = readdir ( $handle )) !== false )
{
2019-01-27 11:55:16 +01:00
if ( is_readable ( $newdir . " / " . $file ) && preg_match ( '/^interface_([0-9]+)_([^_]+)_(.+)\.class\.php$/i' , $file , $reg ))
2011-09-11 20:35:38 +02:00
{
2019-02-26 23:15:28 +01:00
$part1 = $reg [ 1 ];
$part2 = $reg [ 2 ];
$part3 = $reg [ 3 ];
2012-02-19 17:12:17 +01:00
2011-09-11 20:35:38 +02:00
$nbfile ++ ;
2017-06-02 20:01:25 +02:00
2012-01-31 20:32:26 +01:00
// Check if trigger file is disabled by name
2019-01-27 11:55:16 +01:00
if ( preg_match ( '/NORUN$/i' , $file )) continue ;
2011-09-11 20:35:38 +02:00
// Check if trigger file is for a particular module
$qualified = true ;
2012-01-31 20:32:26 +01:00
if ( strtolower ( $reg [ 2 ]) != 'all' )
2011-09-11 20:35:38 +02:00
{
2019-01-27 11:55:16 +01:00
$module = preg_replace ( '/^mod/i' , '' , $reg [ 2 ]);
2011-09-11 20:35:38 +02:00
$constparam = 'MAIN_MODULE_' . strtoupper ( $module );
if ( empty ( $conf -> global -> $constparam )) $qualified = false ;
}
if ( ! $qualified )
{
2017-08-04 11:50:30 +02:00
//dol_syslog(get_class($this)."::run_triggers action=".$action." Triggers for file '".$file."' need module to be enabled", LOG_DEBUG);
2011-09-11 20:35:38 +02:00
continue ;
}
2012-02-19 17:12:17 +01:00
2017-03-18 11:36:48 +01:00
$modName = " Interface " . ucfirst ( $reg [ 3 ]);
//print "file=$file - modName=$modName\n";
2019-01-27 11:55:16 +01:00
if ( in_array ( $modName , $modules )) // $modules = list of modName already loaded
2017-03-18 11:36:48 +01:00
{
$langs -> load ( " errors " );
2017-03-18 11:48:02 +01:00
dol_syslog ( get_class ( $this ) . " ::run_triggers action= " . $action . " " . $langs -> trans ( " ErrorDuplicateTrigger " , $newdir . " / " . $file , $fullpathfiles [ $modName ]), LOG_WARNING );
2017-03-18 11:36:48 +01:00
continue ;
}
2017-06-02 20:01:25 +02:00
2017-03-18 11:36:48 +01:00
try {
//print 'Todo for '.$modName." : ".$newdir.'/'.$file."\n";
include_once $newdir . '/' . $file ;
//print 'Done for '.$modName."\n";
}
catch ( Exception $e )
{
2017-03-18 11:48:02 +01:00
dol_syslog ( 'ko for ' . $modName . " " . $e -> getMessage () . " \n " , LOG_ERR );
2017-03-18 11:36:48 +01:00
}
2017-06-02 20:01:25 +02:00
2012-01-31 20:32:26 +01:00
$modules [ $i ] = $modName ;
$files [ $i ] = $file ;
2017-03-18 11:36:48 +01:00
$fullpathfiles [ $modName ] = $newdir . '/' . $file ;
2012-01-31 20:32:26 +01:00
$orders [ $i ] = $part1 . '_' . $part2 . '_' . $part3 ; // Set sort criteria value
2012-02-19 17:12:17 +01:00
2012-01-31 20:32:26 +01:00
$i ++ ;
}
}
}
}
2012-02-19 17:12:17 +01:00
2012-01-31 20:32:26 +01:00
asort ( $orders );
2017-06-02 20:01:25 +02:00
2012-01-31 20:32:26 +01:00
// Loop on each trigger
foreach ( $orders as $key => $value )
{
$modName = $modules [ $key ];
if ( empty ( $modName )) continue ;
2011-09-11 20:35:38 +02:00
2012-01-31 20:32:26 +01:00
$objMod = new $modName ( $this -> db );
if ( $objMod )
{
2019-02-26 23:15:28 +01:00
$result = 0 ;
if ( method_exists ( $objMod , 'runTrigger' )) // New method to implement
{
//dol_syslog(get_class($this)."::run_triggers action=".$action." Launch runTrigger for file '".$files[$key]."'", LOG_DEBUG);
$result = $objMod -> runTrigger ( $action , $object , $user , $langs , $conf );
}
elseif ( method_exists ( $objMod , 'run_trigger' )) // Deprecated method
{
dol_syslog ( get_class ( $this ) . " ::run_triggers action= " . $action . " Launch old method run_trigger (rename your trigger into runTrigger) for file ' " . $files [ $key ] . " ' " , LOG_WARNING );
$result = $objMod -> run_trigger ( $action , $object , $user , $langs , $conf );
}
else
{
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 );
}
2011-09-11 20:35:38 +02:00
2012-01-31 20:32:26 +01:00
if ( $result > 0 )
{
// Action OK
$nbtotal ++ ;
$nbok ++ ;
2011-09-11 20:35:38 +02:00
}
2012-01-31 20:32:26 +01:00
if ( $result == 0 )
{
// Aucune action faite
$nbtotal ++ ;
}
if ( $result < 0 )
{
// Action KO
2016-06-25 18:48:50 +02:00
//dol_syslog("Error in trigger ".$action." - Nb of error string returned = ".count($objMod->errors), LOG_ERR);
2012-01-31 20:32:26 +01:00
$nbtotal ++ ;
$nbko ++ ;
2019-01-27 11:55:16 +01:00
if ( ! empty ( $objMod -> errors )) $this -> errors = array_merge ( $this -> errors , $objMod -> errors );
2019-01-27 10:49:34 +01:00
elseif ( ! empty ( $objMod -> error )) $this -> errors [] = $objMod -> error ;
2016-06-25 18:48:50 +02:00
//dol_syslog("Error in trigger ".$action." - Nb of error string returned = ".count($this->errors), LOG_ERR);
2012-01-31 20:32:26 +01:00
}
}
else
2019-02-26 23:15:28 +01:00
{
2014-05-13 10:36:01 +02:00
dol_syslog ( get_class ( $this ) . " ::run_triggers action= " . $action . " Failed to instantiate trigger for file ' " . $files [ $key ] . " ' " , LOG_ERR );
2010-12-15 19:15:08 +01:00
}
2011-09-11 20:35:38 +02:00
}
if ( $nbko )
{
2016-06-25 18:48:50 +02:00
dol_syslog ( get_class ( $this ) . " ::run_triggers action= " . $action . " Files found: " . $nbfile . " , Files launched: " . $nbtotal . " , Done: " . $nbok . " , Failed: " . $nbko . " - Nb of error string returned in this->errors = " . count ( $this -> errors ), LOG_ERR );
2011-09-11 20:35:38 +02:00
return - $nbko ;
}
else
{
2012-01-31 20:32:26 +01:00
//dol_syslog(get_class($this)."::run_triggers Files found: ".$nbfile.", Files launched: ".$nbtotal.", Done: ".$nbok.", Failed: ".$nbko, LOG_DEBUG);
2011-09-11 20:35:38 +02:00
return $nbok ;
}
}
/**
2012-01-31 20:32:26 +01:00
* Return list of triggers . Function used by admin page htdoc / admin / triggers .
* List is sorted by trigger filename so by priority to run .
2012-02-19 17:12:17 +01:00
*
2019-02-26 23:15:28 +01:00
* @ param array $forcedirtriggers null = All default directories . This parameter is used by modulebuilder module only .
2017-05-28 14:43:17 +02:00
* @ return array Array list of triggers
2011-09-11 20:35:38 +02:00
*/
2019-02-26 23:15:28 +01:00
public function getTriggersList ( $forcedirtriggers = null )
2011-09-11 20:35:38 +02:00
{
2017-07-16 12:07:59 +02:00
global $conf , $langs , $db ;
2011-09-11 20:35:38 +02:00
$files = array ();
2013-12-10 15:48:44 +01:00
$fullpath = array ();
$relpath = array ();
$iscoreorexternal = array ();
2011-09-11 20:35:38 +02:00
$modules = array ();
$orders = array ();
$i = 0 ;
2019-01-27 11:55:16 +01:00
$dirtriggers = array_merge ( array ( '/core/triggers/' ), $conf -> modules_parts [ 'triggers' ]);
2017-05-28 14:43:17 +02:00
if ( is_array ( $forcedirtriggers ))
{
2019-02-26 23:15:28 +01:00
$dirtriggers = $forcedirtriggers ;
2017-05-28 14:43:17 +02:00
}
2017-06-02 20:01:25 +02:00
2012-02-19 17:12:17 +01:00
foreach ( $dirtriggers as $reldir )
2011-09-11 20:35:38 +02:00
{
2019-01-27 11:55:16 +01:00
$dir = dol_buildpath ( $reldir , 0 );
2012-02-22 16:18:03 +01:00
$newdir = dol_osencode ( $dir );
2011-09-11 20:35:38 +02:00
2012-02-22 16:18:03 +01:00
// Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php at each call)
if ( ! is_dir ( $newdir )) continue ;
2011-09-11 20:35:38 +02:00
2012-02-22 16:18:03 +01:00
$handle = opendir ( $newdir );
2010-12-15 19:15:08 +01:00
if ( is_resource ( $handle ))
{
2011-09-11 20:35:38 +02:00
while (( $file = readdir ( $handle )) !== false )
{
2019-01-27 11:55:16 +01:00
if ( is_readable ( $newdir . '/' . $file ) && preg_match ( '/^interface_([0-9]+)_([^_]+)_(.+)\.class\.php/' , $file , $reg ))
2011-09-11 20:35:38 +02:00
{
2019-01-27 11:55:16 +01:00
if ( preg_match ( '/\.back$/' , $file )) continue ;
2017-07-08 16:52:10 +02:00
2019-02-26 23:15:28 +01:00
$part1 = $reg [ 1 ];
$part2 = $reg [ 2 ];
$part3 = $reg [ 3 ];
2012-02-19 17:12:17 +01:00
2012-01-31 20:32:26 +01:00
$modName = 'Interface' . ucfirst ( $reg [ 3 ]);
2011-09-11 20:35:38 +02:00
//print "file=$file"; print "modName=$modName"; exit;
2019-01-27 11:55:16 +01:00
if ( in_array ( $modName , $modules ))
2011-09-11 20:35:38 +02:00
{
$langs -> load ( " errors " );
2019-01-27 11:55:16 +01:00
print '<div class="error">' . $langs -> trans ( " Error " ) . ' : ' . $langs -> trans ( " ErrorDuplicateTrigger " , $modName , " /htdocs/core/triggers/ " ) . '</div>' ;
2011-09-11 20:35:38 +02:00
}
else
{
2012-08-23 02:04:35 +02:00
include_once $newdir . '/' . $file ;
2011-09-11 20:35:38 +02:00
}
2012-01-31 20:32:26 +01:00
$files [ $i ] = $file ;
2013-12-10 15:48:44 +01:00
$fullpath [ $i ] = $dir . '/' . $file ;
2019-01-27 11:55:16 +01:00
$relpath [ $i ] = preg_replace ( '/^\//' , '' , $reldir ) . '/' . $file ;
2013-12-10 15:48:44 +01:00
$iscoreorexternal [ $i ] = ( $reldir == '/core/triggers/' ? 'internal' : 'external' );
2012-01-31 20:32:26 +01:00
$modules [ $i ] = $modName ;
$orders [ $i ] = $part1 . '_' . $part2 . '_' . $part3 ; // Set sort criteria value
2012-02-19 17:12:17 +01:00
2012-01-31 20:32:26 +01:00
$i ++ ;
2011-09-11 20:35:38 +02:00
}
}
closedir ( $handle );
2010-12-15 19:15:08 +01:00
}
2011-09-11 20:35:38 +02:00
}
asort ( $orders );
$triggers = array ();
$j = 0 ;
// Loop on each trigger
foreach ( $orders as $key => $value )
{
$modName = $modules [ $key ];
2012-01-31 20:32:26 +01:00
if ( empty ( $modName )) continue ;
2013-12-10 16:25:27 +01:00
if ( ! class_exists ( $modName ))
{
2019-02-26 23:15:28 +01:00
print 'Error: A trigger file was found but its class "' . $modName . '" was not found.' . " <br> \n " ;
continue ;
2013-12-10 16:25:27 +01:00
}
2014-05-13 10:36:01 +02:00
2017-07-16 12:07:59 +02:00
$objMod = new $modName ( $db );
2011-09-11 20:35:38 +02:00
// Define disabledbyname and disabledbymodule
$disabledbyname = 0 ;
$disabledbymodule = 1 ;
$module = '' ;
2012-01-31 20:32:26 +01:00
// Check if trigger file is disabled by name
2019-01-27 11:55:16 +01:00
if ( preg_match ( '/NORUN$/i' , $files [ $key ])) $disabledbyname = 1 ;
2012-01-31 20:32:26 +01:00
// Check if trigger file is for a particular module
2019-01-27 11:55:16 +01:00
if ( preg_match ( '/^interface_([0-9]+)_([^_]+)_(.+)\.class\.php/i' , $files [ $key ], $reg ))
2011-09-11 20:35:38 +02:00
{
2019-01-27 11:55:16 +01:00
$module = preg_replace ( '/^mod/i' , '' , $reg [ 2 ]);
2011-09-11 20:35:38 +02:00
$constparam = 'MAIN_MODULE_' . strtoupper ( $module );
2017-08-03 12:19:31 +02:00
if ( strtolower ( $module ) == 'all' ) $disabledbymodule = 0 ;
2019-01-27 10:49:34 +01:00
elseif ( empty ( $conf -> global -> $constparam )) $disabledbymodule = 2 ;
2017-08-03 12:19:31 +02:00
$triggers [ $j ][ 'module' ] = strtolower ( $module );
2011-09-11 20:35:38 +02:00
}
2019-02-26 23:15:28 +01:00
// We set info of modules
2019-01-27 11:55:16 +01:00
$triggers [ $j ][ 'picto' ] = $objMod -> picto ? img_object ( '' , $objMod -> picto ) : img_object ( '' , 'generic' );
2011-09-11 20:35:38 +02:00
$triggers [ $j ][ 'file' ] = $files [ $key ];
2013-12-10 15:48:44 +01:00
$triggers [ $j ][ 'fullpath' ] = $fullpath [ $key ];
$triggers [ $j ][ 'relpath' ] = $relpath [ $key ];
$triggers [ $j ][ 'iscoreorexternal' ] = $iscoreorexternal [ $key ];
2011-09-11 20:35:38 +02:00
$triggers [ $j ][ 'version' ] = $objMod -> getVersion ();
2019-01-27 11:55:16 +01:00
$triggers [ $j ][ 'status' ] = img_picto ( $langs -> trans ( " Active " ), 'tick' );
2017-07-08 15:43:36 +02:00
if ( $disabledbyname > 0 || $disabledbymodule > 1 ) $triggers [ $j ][ 'status' ] = '' ;
2011-09-11 20:35:38 +02:00
$text = '<b>' . $langs -> trans ( " Description " ) . ':</b><br>' ;
$text .= $objMod -> getDesc () . '<br>' ;
$text .= '<br><b>' . $langs -> trans ( " Status " ) . ':</b><br>' ;
if ( $disabledbyname == 1 )
{
$text .= $langs -> trans ( " TriggerDisabledByName " ) . '<br>' ;
2019-01-27 11:55:16 +01:00
if ( $disabledbymodule == 2 ) $text .= $langs -> trans ( " TriggerDisabledAsModuleDisabled " , $module ) . '<br>' ;
2011-09-11 20:35:38 +02:00
}
else
{
if ( $disabledbymodule == 0 ) $text .= $langs -> trans ( " TriggerAlwaysActive " ) . '<br>' ;
2019-01-27 11:55:16 +01:00
if ( $disabledbymodule == 1 ) $text .= $langs -> trans ( " TriggerActiveAsModuleActive " , $module ) . '<br>' ;
if ( $disabledbymodule == 2 ) $text .= $langs -> trans ( " TriggerDisabledAsModuleDisabled " , $module ) . '<br>' ;
2011-09-11 20:35:38 +02:00
}
2012-02-22 14:43:13 +01:00
$triggers [ $j ][ 'info' ] = $text ;
2011-09-11 20:35:38 +02:00
$j ++ ;
}
return $triggers ;
}
2005-04-21 20:49:15 +02:00
}