Passed
Push — CHECK_API ( 78ffdd...fa4f39 )
by Rafael
41:29
created

DolibarrApi::getModuleNamespace()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* Copyright (C) 2015       Jean-François Ferry         <[email protected]>
4
 * Copyright (C) 2016	    Laurent Destailleur		    <[email protected]>
5
 * Copyright (C) 2020		Frédéric France		        <[email protected]>
6
 * Copyright (C) 2024		MDW							<[email protected]>
7
 * Copyright (C) 2024       Rafael San José             <[email protected]>
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21
 */
22
23
namespace Dolibarr\Core\Base;
24
25
use Dolibarr\Code\Api\Classes\DolibarrApiAccess;
26
use DoliDB;
27
use Luracast\Restler\Defaults;
28
use Luracast\Restler\Restler;
29
30
/**
31
 * Class for API REST v1
32
 */
33
class DolibarrApi
34
{
35
    /**
36
     * @var Restler $r Restler object
37
     */
38
    public $r;
39
    /**
40
     * @var DoliDB $db Database object
41
     */
42
    protected $db;
43
44
    /**
45
     * Constructor
46
     *
47
     * @param DoliDB $db Database handler
48
     * @param string $cachedir Cache dir
49
     * @param boolean $refreshCache Update cache
50
     */
51
    public function __construct($db, $cachedir = '', $refreshCache = false)
52
    {
53
        global $conf, $dolibarr_main_url_root;
54
55
        if (empty($cachedir)) {
56
            $cachedir = $conf->api->dir_temp;
57
        }
58
        Defaults::$cacheDirectory = $cachedir;
59
60
        $this->db = $db;
61
        $production_mode = (!getDolGlobalString('API_PRODUCTION_MODE') ? false : true);
62
        $this->r = new Restler($production_mode, $refreshCache);
63
64
        $urlwithouturlroot = preg_replace('/' . preg_quote(DOL_URL_ROOT, '/') . '$/i', '', trim($dolibarr_main_url_root));
65
        $urlwithroot = $urlwithouturlroot . DOL_URL_ROOT; // This is to use external domain name found into config file
66
67
        $urlwithouturlrootautodetect = preg_replace('/' . preg_quote(DOL_URL_ROOT, '/') . '$/i', '', trim(DOL_MAIN_URL_ROOT));
68
        $urlwithrootautodetect = $urlwithouturlroot . DOL_URL_ROOT; // This is to use local domain autodetected by dolibarr from url
69
70
        $this->r->setBaseUrls($urlwithouturlroot, $urlwithouturlrootautodetect);
71
        $this->r->setAPIVersion(1);
72
        //$this->r->setSupportedFormats('json');
73
        //$this->r->setSupportedFormats('jsonFormat');
74
    }
75
76
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
77
78
    public static function getModules($modulesdir = null)
79
    {
80
        if (!isset($modulesdir)) {
81
            $modulesdir = dolGetModulesDirs();
82
        }
83
        return static::_getModules($modulesdir);
84
    }
85
86
    private static function _getModules($modulesdir)
87
    {
88
        $result = [];
89
        foreach ($modulesdir as $dir) {
90
            // Search available module
91
            dol_syslog("Scan directory " . $dir . " for module descriptor files, then search for API files");
92
93
            $handle = @opendir(dol_osencode($dir));
94
            if (is_resource($handle)) {
95
                while (($file = readdir($handle)) !== false) {
96
97
                    if (is_readable($dir . $file)) {
98
                        $module = DolibarrModules::_getModuleName($file);
99
                        if (!DolibarrModules::isActivated($module)) {
100
                            continue;
101
                        }
102
103
                        $moduledirforclass = static::getFolderForModuleCode($module);
104
                        $moduleClasses = DolibarrApi::getModuleApiClasses($moduledirforclass);
105
106
                        if (empty($moduleClasses)) {
107
                            continue;
108
                        }
109
110
                        foreach ($moduleClasses as $name => $module) {
111
                            $result[$name] = $module;
112
                        }
113
                    }
114
                }
115
            }
116
        }
117
        return $result;
118
    }
119
120
    /**
121
     * Get name of directory where the api_...class.php file is stored
122
     *
123
     * @param string $moduleobject Module object name
124
     * @return  string                    Directory name
125
     */
126
    public static function getFolderForModuleCode($moduleobject)
127
    {
128
        $mapping = [
129
            'Accounting' => 'Accountancy',
130
            'Adherent' => 'Adherents',
131
            'Agenda' => null,
132
            'Ai' => 'Ai',
133
            'Api' => 'Api',
134
            'Asset' => 'Asset',
135
        ];
136
137
        if (isset($mapping[$moduleobject])) {
138
            return $mapping[$moduleobject];
139
        }
140
141
        $moduledirforclass = $moduleobject;
142
        if ($moduledirforclass != 'api') {
143
            $moduledirforclass = preg_replace('/api$/i', '', $moduledirforclass);
144
        }
145
146
        if ($moduleobject == 'contracts') {
147
            $moduledirforclass = 'contrat';
148
        } elseif (in_array($moduleobject, array('admin', 'login', 'setup', 'access', 'status', 'tools', 'documents'))) {
149
            $moduledirforclass = 'api';
150
        } elseif ($moduleobject == 'contact' || $moduleobject == 'contacts' || $moduleobject == 'customer' || $moduleobject == 'thirdparty' || $moduleobject == 'thirdparties') {
151
            $moduledirforclass = 'societe';
152
        } elseif ($moduleobject == 'propale' || $moduleobject == 'proposals') {
153
            $moduledirforclass = 'comm/propal';
154
        } elseif ($moduleobject == 'agenda' || $moduleobject == 'agendaevents') {
155
            $moduledirforclass = 'comm/action';
156
        } elseif ($moduleobject == 'adherent' || $moduleobject == 'members' || $moduleobject == 'memberstypes' || $moduleobject == 'subscriptions') {
157
            $moduledirforclass = 'adherents';
158
        } elseif ($moduleobject == 'don' || $moduleobject == 'donations') {
159
            $moduledirforclass = 'don';
160
        } elseif ($moduleobject == 'banque' || $moduleobject == 'bankaccounts') {
161
            $moduledirforclass = 'compta/bank';
162
        } elseif ($moduleobject == 'category' || $moduleobject == 'categorie') {
163
            $moduledirforclass = 'categories';
164
        } elseif ($moduleobject == 'order' || $moduleobject == 'orders') {
165
            $moduledirforclass = 'commande';
166
        } elseif ($moduleobject == 'shipments') {
167
            $moduledirforclass = 'expedition';
168
        } elseif ($moduleobject == 'multicurrencies') {
169
            $moduledirforclass = 'multicurrency';
170
        } elseif ($moduleobject == 'facture' || $moduleobject == 'invoice' || $moduleobject == 'invoices') {
171
            $moduledirforclass = 'compta/facture';
172
        } elseif ($moduleobject == 'project' || $moduleobject == 'projects' || $moduleobject == 'task' || $moduleobject == 'tasks') {
173
            $moduledirforclass = 'projet';
174
        } elseif ($moduleobject == 'stock' || $moduleobject == 'stockmovements' || $moduleobject == 'warehouses') {
175
            $moduledirforclass = 'product/stock';
176
        } elseif ($moduleobject == 'supplierproposals' || $moduleobject == 'supplierproposal' || $moduleobject == 'supplier_proposal') {
177
            $moduledirforclass = 'supplier_proposal';
178
        } elseif ($moduleobject == 'fournisseur' || $moduleobject == 'supplierinvoices' || $moduleobject == 'supplierorders') {
179
            $moduledirforclass = 'fourn';
180
        } elseif ($moduleobject == 'ficheinter' || $moduleobject == 'interventions') {
181
            $moduledirforclass = 'fichinter';
182
        } elseif ($moduleobject == 'mos') {
183
            $moduledirforclass = 'mrp';
184
        } elseif ($moduleobject == 'workstations') {
185
            $moduledirforclass = 'workstation';
186
        } elseif ($moduleobject == 'accounting') {
187
            $moduledirforclass = 'accountancy';
188
        } elseif (in_array($moduleobject, array('products', 'expensereports', 'users', 'tickets', 'boms', 'receptions', 'partnerships', 'recruitments'))) {
189
            $moduledirforclass = preg_replace('/s$/', '', $moduleobject);
190
        } elseif ($moduleobject == 'paymentsalaries') {
191
            $moduledirforclass = 'salaries';
192
        } elseif ($moduleobject == 'paymentexpensereports') {
193
            $moduledirforclass = 'expensereport';
194
        }
195
196
        return $moduledirforclass;
197
    }
198
199
    public static function getModuleApiClasses($moduleName): array
200
    {
201
        $result = [];
202
        $apiPath = realpath(constant('BASE_PATH') . '/../Dolibarr/Code/' . $moduleName . '/Api');
203
        if ($apiPath === false) {
204
            return $result;
205
        }
206
207
        $dir = opendir($apiPath);
208
        while (($file = readdir($dir)) !== false) {
209
            if (pathinfo($file, PATHINFO_EXTENSION) !== 'php') {
210
                continue;
211
            }
212
            $className = pathinfo($file, PATHINFO_FILENAME);
213
            $result[$className] = static::getModuleNamespace($moduleName, $className);
214
        }
215
        closedir($dir);
216
        return $result;
217
    }
218
219
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
220
221
    /**
222
     * Obtains the namespace of an API module.
223
     *
224
     * @param $moduleName
225
     * @param $className
226
     * @return string
227
     */
228
    public static function getModuleNamespace($moduleName, $className): string
229
    {
230
        return 'Dolibarr\\Code\\' . $moduleName . '\\Api\\' . $className;
231
    }
232
233
    /**
234
     * Obtains an instance of $moduleName/$className, or null.
235
     *
236
     * @param $moduleName
237
     * @param $className
238
     * @return mixed
239
     */
240
    public static function getModule($moduleName, $className)
241
    {
242
        $namespace = static::getModuleNamespace($moduleName, $className);
243
        if (!is_dir)
0 ignored issues
show
Bug introduced by
The constant Dolibarr\Core\Base\is_dir was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
244
            dump(['namespace' => $namespace]);
245
246
        return new $namespace();
247
    }
248
249
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
250
251
    /**
252
     * Check access by user to a given resource
253
     *
254
     * @param string $resource element to check
255
     * @param int $resource_id Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional).
256
     * @param string $dbtablename 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity. Not used if objectid is null (optional)
257
     * @param string $feature2 Feature to check, second level of permission (optional). Can be or check with 'level1|level2'.
258
     * @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional)
259
     * @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional)
260
     * @return bool
261
     */
262
    protected static function _checkAccessToResource($resource, $resource_id = 0, $dbtablename = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid')
263
    {
264
        // phpcs:enable
265
        // Features/modules to check
266
        $featuresarray = array($resource);
267
        if (preg_match('/&/', $resource)) {
268
            $featuresarray = explode("&", $resource);
269
        } elseif (preg_match('/\|/', $resource)) {
270
            $featuresarray = explode("|", $resource);
271
        }
272
273
        // More subfeatures to check
274
        if (!empty($feature2)) {
275
            $feature2 = explode("|", $feature2);
276
        }
277
278
        return checkUserAccessToObject(DolibarrApiAccess::$user, $featuresarray, $resource_id, $dbtablename, $feature2, $dbt_keyfield, $dbt_select);
279
    }
280
281
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
282
283
    /**
284
     * Function to forge a SQL criteria from a Generic filter string.
285
     * Function no more used. Kept for backward compatibility with old APIs of modules
286
     *
287
     * @param array $matches Array of found string by regex search.
288
     *                              Each entry is 1 and only 1 criteria.
289
     *                              Example: "t.ref:like:'SO-%'", "t.date_creation:<:'20160101'", "t.date_creation:<:'2016-01-01 12:30:00'", "t.nature:is:NULL", "t.field2:isnot:NULL"
290
     * @return string               Forged criteria. Example: "t.field like 'abc%'"
291
     */
292
    protected static function _forge_criteria_callback($matches)
293
    {
294
        return dolForgeCriteriaCallback($matches);
295
    }
296
297
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
298
299
    /**
300
     * Check and convert a string depending on its type/name.
301
     *
302
     * @param string $field Field name
303
     * @param string|array $value Value to check/clean
304
     * @param Object $object Object
305
     * @return  string|array                Value cleaned
306
     */
307
    protected function _checkValForAPI($field, $value, $object)
308
    {
309
        // phpcs:enable
310
        if (!is_array($value)) {
311
            // Sanitize the value using its type declared into ->fields of $object
312
            if (!empty($object->fields) && !empty($object->fields[$field]) && !empty($object->fields[$field]['type'])) {
313
                if (strpos($object->fields[$field]['type'], 'int') || strpos($object->fields[$field]['type'], 'double') || in_array($object->fields[$field]['type'], array('real', 'price', 'stock'))) {
314
                    return sanitizeVal($value, 'int');
315
                }
316
                if ($object->fields[$field]['type'] == 'html') {
317
                    return sanitizeVal($value, 'restricthtml');
318
                }
319
                if ($object->fields[$field]['type'] == 'select') {
320
                    // Check values are in the list of possible 'options'
321
                    // TODO
322
                }
323
                if ($object->fields[$field]['type'] == 'sellist' || $object->fields[$field]['type'] == 'checkbox') {
324
                    // TODO
325
                }
326
                if ($object->fields[$field]['type'] == 'boolean' || $object->fields[$field]['type'] == 'radio') {
327
                    // TODO
328
                }
329
                if ($object->fields[$field]['type'] == 'email') {
330
                    return sanitizeVal($value, 'email');
331
                }
332
                if ($object->fields[$field]['type'] == 'password') {
333
                    return sanitizeVal($value, 'none');
334
                }
335
                // Others will use 'alphanohtml'
336
            }
337
338
            if (in_array($field, array('note', 'note_private', 'note_public', 'desc', 'description'))) {
339
                return sanitizeVal($value, 'restricthtml');
340
            } else {
341
                return sanitizeVal($value, 'alphanohtml');
342
            }
343
        } else {    // Example when $field = 'extrafields' and $value = content of $object->array_options
344
            $newarrayvalue = array();
345
            foreach ($value as $tmpkey => $tmpvalue) {
346
                $newarrayvalue[$tmpkey] = $this->_checkValForAPI($tmpkey, $tmpvalue, $object);
347
            }
348
349
            return $newarrayvalue;
350
        }
351
    }
352
353
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
354
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
355
356
    /**
357
     * Filter properties that will be returned on object
358
     *
359
     * @param Object $object Object to clean
360
     * @param String $properties Comma separated list of properties names
361
     * @return  Object                  Object with cleaned properties
362
     */
363
    protected function _filterObjectProperties($object, $properties)
364
    {
365
        // phpcs:enable
366
        // If properties is empty, we return all properties
367
        if (empty($properties)) {
368
            return $object;
369
        }
370
371
        // Copy of exploded array for efficiency
372
        $arr_properties = explode(',', $properties);
373
        $magic_properties = array();
374
        $real_properties = get_object_vars($object);
375
376
        // Unsetting real properties may unset magic properties.
377
        // We keep a copy of the requested magic properties
378
        foreach ($arr_properties as $key) {
379
            if (!array_key_exists($key, $real_properties)) {
380
                // Not a real property,
381
                // check if $key is a magic property (we want to keep '$obj->$key')
382
                if (property_exists($object, $key) && isset($object->$key)) {
383
                    $magic_properties[$key] = $object->$key;
384
                }
385
            }
386
        }
387
388
        // Filter real properties (may indirectly unset magic properties)
389
        foreach (get_object_vars($object) as $key => $value) {
390
            if (!in_array($key, $arr_properties)) {
391
                unset($object->$key);
392
            }
393
        }
394
395
        // Restore the magic properties
396
        foreach ($magic_properties as $key => $value) {
397
            $object->$key = $value;
398
        }
399
400
        return $object;
401
    }
402
403
    /**
404
     * Clean sensible object datas
405
     *
406
     * @param Object $object Object to clean
407
     * @return  Object              Object with cleaned properties
408
     */
409
    protected function _cleanObjectDatas($object)
410
    {
411
        // phpcs:enable
412
        // Remove $db object property for object
413
        unset($object->db);
414
        unset($object->isextrafieldmanaged);
415
        unset($object->ismultientitymanaged);
416
        unset($object->restrictiononfksoc);
417
        unset($object->table_rowid);
418
        unset($object->pass);
419
        unset($object->pass_indatabase);
420
421
        // Remove linkedObjects. We should already have and keep only linkedObjectsIds that avoid huge responses
422
        unset($object->linkedObjects);
423
        //unset($object->lines[$i]->linked_objects);        // This is the array to create linked object during create
424
425
        unset($object->fields);
426
        unset($object->oldline);
427
428
        unset($object->error);
429
        unset($object->errors);
430
        unset($object->errorhidden);
431
432
        unset($object->ref_previous);
433
        unset($object->ref_next);
434
        unset($object->imgWidth);
435
        unset($object->imgHeight);
436
        unset($object->barcode_type_code);
437
        unset($object->barcode_type_label);
438
439
        unset($object->mode_reglement);     // We use mode_reglement_id now
440
        unset($object->cond_reglement);     // We use cond_reglement_id now
441
        unset($object->note);               // We use note_public or note_private now
442
        unset($object->contact);            // We use contact_id now
443
        unset($object->thirdparty);         // We use thirdparty_id or fk_soc or socid now
444
445
        unset($object->projet); // Should be fk_project
446
        unset($object->project); // Should be fk_project
447
        unset($object->fk_projet); // Should be fk_project
448
        unset($object->author); // Should be fk_user_author
449
        unset($object->timespent_old_duration);
450
        unset($object->timespent_id);
451
        unset($object->timespent_duration);
452
        unset($object->timespent_date);
453
        unset($object->timespent_datehour);
454
        unset($object->timespent_withhour);
455
        unset($object->timespent_fk_user);
456
        unset($object->timespent_note);
457
        unset($object->fk_delivery_address);
458
        unset($object->model_pdf);
459
        unset($object->sendtoid);
460
        unset($object->name_bis);
461
        unset($object->newref);
462
        unset($object->oldref);
463
        unset($object->alreadypaid);
464
        unset($object->openid);
465
        unset($object->fk_bank);
466
        unset($object->showphoto_on_popup);
467
        unset($object->nb);
468
        unset($object->nbphoto);
469
        unset($object->output);
470
        unset($object->tpl);
471
        //unset($object->libelle);
472
473
        unset($object->stats_propale);
474
        unset($object->stats_commande);
475
        unset($object->stats_contrat);
476
        unset($object->stats_facture);
477
        unset($object->stats_commande_fournisseur);
478
        unset($object->stats_reception);
479
        unset($object->stats_mrptoconsume);
480
        unset($object->stats_mrptoproduce);
481
482
        unset($object->origin_object);
483
        unset($object->origin);
484
        unset($object->element);
485
        unset($object->element_for_permission);
486
        unset($object->fk_element);
487
        unset($object->table_element);
488
        unset($object->table_element_line);
489
        unset($object->class_element_line);
490
        unset($object->picto);
491
        unset($object->linked_objects);
492
493
        unset($object->fieldsforcombobox);
494
        unset($object->regeximgext);
495
496
        unset($object->skip_update_total);
497
        unset($object->context);
498
        unset($object->next_prev_filter);
499
500
        unset($object->region);
501
        unset($object->region_code);
502
        unset($object->country);
503
        unset($object->state);
504
        unset($object->state_code);
505
        unset($object->fk_departement);
506
        unset($object->departement);
507
        unset($object->departement_code);
508
509
        unset($object->libelle_statut);
510
        unset($object->libelle_paiement);
511
        unset($object->labelStatus);
512
        unset($object->labelStatusShort);
513
514
        unset($object->actionmsg);
515
        unset($object->actionmsg2);
516
517
        unset($object->prefix_comm);
518
519
        if (!isset($object->table_element) || $object->table_element != 'ticket') {
520
            unset($object->comments);
521
        }
522
523
        // Remove the $oldcopy property because it is not supported by the JSON
524
        // encoder. The following error is generated when trying to serialize
525
        // it: "Error encoding/decoding JSON: Type is not supported"
526
        // Note: Event if this property was correctly handled by the JSON
527
        // encoder, it should be ignored because keeping it would let the API
528
        // have a very strange behavior: calling PUT and then GET on the same
529
        // resource would give different results:
530
        // PUT /objects/{id} -> returns object with oldcopy = previous version of the object
531
        // GET /objects/{id} -> returns object with oldcopy empty
532
        unset($object->oldcopy);
533
534
        // If object has lines, remove $db property
535
        if (isset($object->lines) && is_array($object->lines) && count($object->lines) > 0) {
536
            $nboflines = count($object->lines);
537
            for ($i = 0; $i < $nboflines; $i++) {
538
                $this->_cleanObjectDatas($object->lines[$i]);
539
540
                unset($object->lines[$i]->contact);
541
                unset($object->lines[$i]->contact_id);
542
                unset($object->lines[$i]->country);
543
                unset($object->lines[$i]->country_id);
544
                unset($object->lines[$i]->country_code);
545
                unset($object->lines[$i]->mode_reglement_id);
546
                unset($object->lines[$i]->mode_reglement_code);
547
                unset($object->lines[$i]->mode_reglement);
548
                unset($object->lines[$i]->cond_reglement_id);
549
                unset($object->lines[$i]->cond_reglement_code);
550
                unset($object->lines[$i]->cond_reglement);
551
                unset($object->lines[$i]->fk_delivery_address);
552
                unset($object->lines[$i]->fk_projet);
553
                unset($object->lines[$i]->fk_project);
554
                unset($object->lines[$i]->thirdparty);
555
                unset($object->lines[$i]->user);
556
                unset($object->lines[$i]->model_pdf);
557
                unset($object->lines[$i]->note_public);
558
                unset($object->lines[$i]->note_private);
559
                unset($object->lines[$i]->fk_incoterms);
560
                unset($object->lines[$i]->label_incoterms);
561
                unset($object->lines[$i]->location_incoterms);
562
                unset($object->lines[$i]->name);
563
                unset($object->lines[$i]->lastname);
564
                unset($object->lines[$i]->firstname);
565
                unset($object->lines[$i]->civility_id);
566
                unset($object->lines[$i]->fk_multicurrency);
567
                unset($object->lines[$i]->multicurrency_code);
568
                unset($object->lines[$i]->shipping_method_id);
569
            }
570
        }
571
572
        if (!empty($object->thirdparty) && is_object($object->thirdparty)) {
573
            $this->_cleanObjectDatas($object->thirdparty);
574
        }
575
576
        if (!empty($object->product) && is_object($object->product)) {
577
            $this->_cleanObjectDatas($object->product);
578
        }
579
580
        return $object;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $object also could return the type object which is incompatible with the documented return type object.
Loading history...
581
    }
582
583
    /**
584
     * Return if a $sqlfilters parameter is valid
585
     * Function no more used. Kept for backward compatibility with old APIs of modules
586
     *
587
     * @param string $sqlfilters sqlfilter string
588
     * @param string $error Error message
589
     * @return  boolean|string                  True if valid, False if not valid
590
     */
591
    protected function _checkFilters($sqlfilters, &$error = '')
592
    {
593
        // phpcs:enable
594
        $firstandlastparenthesis = 0;
595
        return dolCheckFilters($sqlfilters, $error, $firstandlastparenthesis);
596
    }
597
}
598