Passed
Push — master ( 0f9140...c4489d )
by Alxarafe
22:27
created

Base/AlInterfaces.php (2 issues)

Labels
Severity
1
<?php
2
/* Copyright (C) 2018       Alxarafe            <[email protected]>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
 */
17
namespace Alixar\Base;
18
19
use Alxarafe\Helpers\Config;
20
use Alixar\Helpers\Globals;
21
use Alixar\Helpers\AlDolUtils;
22
23
// require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
24
25
class AlInterfaces
26
{
27
28
    var $dir;    // Directory with all core and external triggers files
29
30
    /**
31
     * @var string[] Error codes (or messages)
32
     */
33
    public $errors = array();
34
35
    /**
36
     * 	Constructor
37
     *
38
     *  @param		DoliDB		$db      Database handler
0 ignored issues
show
The type Alixar\Base\DoliDB was not found. Did you mean DoliDB? If so, make sure to prefix the type with \.
Loading history...
39
     */
40
    function __construct()
41
    {
42
        // Config::$dbEngine = $db;
43
    }
44
45
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
46
    /**
47
     *   Function called when a Dolibarr business event occurs
48
     *   This function call all qualified triggers.
49
     *
50
     *   @param		string		$action     Trigger event code
51
     *   @param     object		$object     Objet concerned. Some context information may also be provided into array property object->context.
52
     *   @param     User		$user       Objet user
53
     *   @param     Lang		$langs      Objet lang
54
     *   @param     Conf		$conf       Objet conf
55
     *   @return    int         			Nb of triggers ran if no error, -Nb of triggers with errors otherwise.
56
     */
57
    function run_triggers($action, $object/* , $user, $langs, $conf */)
58
    {
59
        $user = Globals::$user;
60
        $langs = Globals::$langs;
61
        $conf = Globals::$conf;
62
63
        // phpcs:enable
64
        // Check parameters
65
        if (!is_object($object) || !is_object($conf)) { // Error
66
            $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);
67
            DolUtils::dol_syslog(get_class($this) . '::run_triggers ' . $this->error, LOG_ERR);
68
            $this->errors[] = $this->error;
69
            return -1;
70
        }
71
        if (!is_object($langs)) { // Warning
72
            DolUtils::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);
73
        }
74
        /*
75
          if (!is_object($user)) {     // Warning
76
          DolUtils::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);
77
          global $db;
78
          $user = new User($db);
79
          }
80
         */
81
82
        $nbfile = $nbtotal = $nbok = $nbko = 0;
83
84
        $files = array();
85
        $modules = array();
86
        $orders = array();
87
        $i = 0;
88
89
        // $dirtriggers = array_merge(array('/core/triggers'), Globals::$conf->modules_parts['triggers']);
90
        $dirtriggers = array_merge(array(BASE_PATH . '/Helpers/triggers'), Globals::$conf->modules_parts['triggers']);
91
        foreach ($dirtriggers as $reldir) {
92
            //$dir = DolUtils::dol_buildpath($reldir, 0);
93
            //$newdir = DolUtils::dol_osencode($dir);
94
            $newdir = DolUtils::dol_buildpath($reldir, 0);
95
            //print "xx".$dir;exit;
96
            // Check if directory exists (we do not use dol_is_dir to avoir loading files.lib.php at each call)
97
            if (!is_dir($newdir))
98
                continue;
99
100
            $handle = opendir($newdir);
101
            if (is_resource($handle)) {
102
                while (($file = readdir($handle)) !== false) {
103
                    if (is_readable($newdir . "/" . $file) && preg_match('/^interface_([0-9]+)_([^_]+)_(.+)\.class\.php$/i', $file, $reg)) {
104
                        $part1 = $reg[1];
105
                        $part2 = $reg[2];
106
                        $part3 = $reg[3];
107
108
                        $nbfile++;
109
110
                        // Check if trigger file is disabled by name
111
                        if (preg_match('/NORUN$/i', $file))
112
                            continue;
113
                        // Check if trigger file is for a particular module
114
                        $qualified = true;
115
                        if (strtolower($reg[2]) != 'all') {
116
                            $module = preg_replace('/^mod/i', '', $reg[2]);
117
                            $constparam = 'MAIN_MODULE_' . strtoupper($module);
118
                            if (empty(Globals::$conf->global->$constparam))
119
                                $qualified = false;
120
                        }
121
122
                        if (!$qualified) {
123
                            //DolUtils::dol_syslog(get_class($this)."::run_triggers action=".$action." Triggers for file '".$file."' need module to be enabled", LOG_DEBUG);
124
                            continue;
125
                        }
126
127
                        $modName = "Interface" . ucfirst($reg[3]);
128
                        //print "file=$file - modName=$modName\n";
129
                        if (in_array($modName, $modules)) {    // $modules = list of modName already loaded
130
                            $langs->load("errors");
131
                            DolUtils::dol_syslog(get_class($this) . "::run_triggers action=" . $action . " " . $langs->trans("ErrorDuplicateTrigger", $newdir . "/" . $file, $fullpathfiles[$modName]), LOG_WARNING);
132
                            continue;
133
                        }
134
135
                        try {
136
                            //print 'Todo for '.$modName." : ".$newdir.'/'.$file."\n";
137
                            include_once $newdir . '/' . $file;
138
                            //print 'Done for '.$modName."\n";
139
                        } catch (Exception $e) {
0 ignored issues
show
The type Alixar\Base\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
140
                            DolUtils::dol_syslog('ko for ' . $modName . " " . $e->getMessage() . "\n", LOG_ERR);
141
                        }
142
143
                        $modules[$i] = $modName;
144
                        $files[$i] = $file;
145
                        $fullpathfiles[$modName] = $newdir . '/' . $file;
146
                        $orders[$i] = $part1 . '_' . $part2 . '_' . $part3;   // Set sort criteria value
147
148
                        $i++;
149
                    }
150
                }
151
            }
152
        }
153
154
        asort($orders);
155
156
        // Loop on each trigger
157
        foreach ($orders as $key => $value) {
158
            $modName = $modules[$key];
159
            if (empty($modName))
160
                continue;
161
162
            $objMod = new $modName();
163
            if ($objMod) {
164
                $result = 0;
165
166
                if (method_exists($objMod, 'runTrigger')) { // New method to implement
167
                    //DolUtils::dol_syslog(get_class($this)."::run_triggers action=".$action." Launch runTrigger for file '".$files[$key]."'", LOG_DEBUG);
168
                    $result = $objMod->runTrigger($action, $object, $user, $langs, $conf);
169
                } elseif (method_exists($objMod, 'run_trigger')) { // Deprecated method
170
                    DolUtils::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);
171
                    $result = $objMod->run_trigger($action, $object, $user, $langs, $conf);
172
                } else {
173
                    DolUtils::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);
174
                }
175
176
                if ($result > 0) {
177
                    // Action OK
178
                    $nbtotal++;
179
                    $nbok++;
180
                }
181
                if ($result == 0) {
182
                    // Aucune action faite
183
                    $nbtotal++;
184
                }
185
                if ($result < 0) {
186
                    // Action KO
187
                    //DolUtils::dol_syslog("Error in trigger ".$action." - Nb of error string returned = ".count($objMod->errors), LOG_ERR);
188
                    $nbtotal++;
189
                    $nbko++;
190
                    if (!empty($objMod->errors))
191
                        $this->errors = array_merge($this->errors, $objMod->errors);
192
                    else if (!empty($objMod->error))
193
                        $this->errors[] = $objMod->error;
194
                    //DolUtils::dol_syslog("Error in trigger ".$action." - Nb of error string returned = ".count($this->errors), LOG_ERR);
195
                }
196
            }
197
            else {
198
                DolUtils::dol_syslog(get_class($this) . "::run_triggers action=" . $action . " Failed to instantiate trigger for file '" . $files[$key] . "'", LOG_ERR);
199
            }
200
        }
201
202
        if ($nbko) {
203
            DolUtils::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);
204
            return -$nbko;
205
        } else {
206
            //DolUtils::dol_syslog(get_class($this)."::run_triggers Files found: ".$nbfile.", Files launched: ".$nbtotal.", Done: ".$nbok.", Failed: ".$nbko, LOG_DEBUG);
207
            return $nbok;
208
        }
209
    }
210
211
    /**
212
     *  Return list of triggers. Function used by admin page htdoc/admin/triggers.
213
     *  List is sorted by trigger filename so by priority to run.
214
     *
215
     * 	@param	array		$forcedirtriggers		null=All default directories. This parameter is used by modulebuilder module only.
216
     * 	@return	array								Array list of triggers
217
     */
218
    function getTriggersList($forcedirtriggers = null)
219
    {
220
        // global $conf, $langs, $db;
221
        $conf = Globals::$conf;
222
        $langs = Globals::$langs;
223
        $db = Config::$dbEngine;
224
225
        $files = array();
226
        $fullpath = array();
227
        $relpath = array();
228
        $iscoreorexternal = array();
229
        $modules = array();
230
        $orders = array();
231
        $i = 0;
232
233
        $dirtriggers = array_merge(array('/core/triggers/'), Globals::$conf->modules_parts['triggers']);
234
        if (is_array($forcedirtriggers)) {
235
            $dirtriggers = $forcedirtriggers;
236
        }
237
238
        foreach ($dirtriggers as $reldir) {
239
            $dir = DolUtils::dol_buildpath($reldir, 0);
240
            $newdir = DolUtils::dol_osencode($dir);
241
242
            // Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php at each call)
243
            if (!is_dir($newdir))
244
                continue;
245
246
            $handle = opendir($newdir);
247
            if (is_resource($handle)) {
248
                while (($file = readdir($handle)) !== false) {
249
                    if (is_readable($newdir . '/' . $file) && preg_match('/^interface_([0-9]+)_([^_]+)_(.+)\.class\.php/', $file, $reg)) {
250
                        if (preg_match('/\.back$/', $file))
251
                            continue;
252
253
                        $part1 = $reg[1];
254
                        $part2 = $reg[2];
255
                        $part3 = $reg[3];
256
257
                        $modName = 'Interface' . ucfirst($reg[3]);
258
                        //print "file=$file"; print "modName=$modName"; exit;
259
                        if (in_array($modName, $modules)) {
260
                            $langs->load("errors");
261
                            print '<div class="error">' . $langs->trans("Error") . ' : ' . $langs->trans("ErrorDuplicateTrigger", $modName, "/htdocs/core/triggers/") . '</div>';
262
                        } else {
263
                            include_once $newdir . '/' . $file;
264
                        }
265
266
                        $files[$i] = $file;
267
                        $fullpath[$i] = $dir . '/' . $file;
268
                        $relpath[$i] = preg_replace('/^\//', '', $reldir) . '/' . $file;
269
                        $iscoreorexternal[$i] = ($reldir == '/core/triggers/' ? 'internal' : 'external');
270
                        $modules[$i] = $modName;
271
                        $orders[$i] = $part1 . '_' . $part2 . '_' . $part3;   // Set sort criteria value
272
273
                        $i++;
274
                    }
275
                }
276
                closedir($handle);
277
            }
278
        }
279
280
        asort($orders);
281
282
        $triggers = array();
283
        $j = 0;
284
285
        // Loop on each trigger
286
        foreach ($orders as $key => $value) {
287
            $modName = $modules[$key];
288
            if (empty($modName))
289
                continue;
290
291
            if (!class_exists($modName)) {
292
                print 'Error: A trigger file was found but its class "' . $modName . '" was not found.' . "<br>\n";
293
                continue;
294
            }
295
296
            $objMod = new $modName($db);
297
298
            // Define disabledbyname and disabledbymodule
299
            $disabledbyname = 0;
300
            $disabledbymodule = 1;
301
            $module = '';
302
303
            // Check if trigger file is disabled by name
304
            if (preg_match('/NORUN$/i', $files[$key]))
305
                $disabledbyname = 1;
306
            // Check if trigger file is for a particular module
307
            if (preg_match('/^interface_([0-9]+)_([^_]+)_(.+)\.class\.php/i', $files[$key], $reg)) {
308
                $module = preg_replace('/^mod/i', '', $reg[2]);
309
                $constparam = 'MAIN_MODULE_' . strtoupper($module);
310
                if (strtolower($module) == 'all')
311
                    $disabledbymodule = 0;
312
                else if (empty(Globals::$conf->global->$constparam))
313
                    $disabledbymodule = 2;
314
                $triggers[$j]['module'] = strtolower($module);
315
            }
316
317
            // We set info of modules
318
            $triggers[$j]['picto'] = $objMod->picto ? img_object('', $objMod->picto) : img_object('', 'generic');
319
            $triggers[$j]['file'] = $files[$key];
320
            $triggers[$j]['fullpath'] = $fullpath[$key];
321
            $triggers[$j]['relpath'] = $relpath[$key];
322
            $triggers[$j]['iscoreorexternal'] = $iscoreorexternal[$key];
323
            $triggers[$j]['version'] = $objMod->getVersion();
324
            $triggers[$j]['status'] = img_picto($langs->trans("Active"), 'tick');
325
            if ($disabledbyname > 0 || $disabledbymodule > 1)
326
                $triggers[$j]['status'] = '';
327
328
            $text = '<b>' . $langs->trans("Description") . ':</b><br>';
329
            $text .= $objMod->getDesc() . '<br>';
330
            $text .= '<br><b>' . $langs->trans("Status") . ':</b><br>';
331
            if ($disabledbyname == 1) {
332
                $text .= $langs->trans("TriggerDisabledByName") . '<br>';
333
                if ($disabledbymodule == 2)
334
                    $text .= $langs->trans("TriggerDisabledAsModuleDisabled", $module) . '<br>';
335
            }
336
            else {
337
                if ($disabledbymodule == 0)
338
                    $text .= $langs->trans("TriggerAlwaysActive") . '<br>';
339
                if ($disabledbymodule == 1)
340
                    $text .= $langs->trans("TriggerActiveAsModuleActive", $module) . '<br>';
341
                if ($disabledbymodule == 2)
342
                    $text .= $langs->trans("TriggerDisabledAsModuleDisabled", $module) . '<br>';
343
            }
344
345
            $triggers[$j]['info'] = $text;
346
            $j++;
347
        }
348
        return $triggers;
349
    }
350
}
351