Passed
Push — master ( 65bdac...4e88da )
by Alxarafe
32:38
created

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