Passed
Branch develop (7b8a20)
by
unknown
32:48
created

Setup::getListOfTowns()   B

Complexity

Conditions 10
Paths 76

Size

Total Lines 45
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 26
c 0
b 0
f 0
nc 76
nop 8
dl 0
loc 45
rs 7.6666

How to fix   Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/* Copyright (C) 2016   Xebax Christy           <[email protected]>
3
 * Copyright (C) 2016	Laurent Destailleur		<[email protected]>
4
 * Copyright (C) 2017	Regis Houssin	        <[email protected]>
5
 * Copyright (C) 2017	Neil Orley	            <[email protected]>
6
 * Copyright (C) 2018   Frédéric France         <[email protected]>
7
 * Copyright (C) 2018-2020   Thibault FOUCART        <[email protected]>
8
 *
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 3 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22
 */
23
24
use Luracast\Restler\RestException;
25
26
require_once DOL_DOCUMENT_ROOT.'/main.inc.php';
27
require_once DOL_DOCUMENT_ROOT.'/core/class/cstate.class.php';
28
require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php';
29
30
/**
31
 * API class for dictionaries
32
 *
33
 * @access protected
34
 * @class DolibarrApiAccess {@requires user,external}
35
 */
36
class Setup extends DolibarrApi
37
{
38
    private $translations = null;
39
40
    /**
41
     * Constructor
42
     */
43
    public function __construct()
44
    {
45
        global $db;
46
        $this->db = $db;
47
    }
48
49
    /**
50
     * Get the list of ordering methods.
51
     *
52
     * @param string    $sortfield  Sort field
53
     * @param string    $sortorder  Sort order
54
     * @param int       $limit      Number of items per page
55
     * @param int       $page       Page number {@min 0}
56
     * @param int       $active     Payment type is active or not {@min 0} {@max 1}
57
     * @param string    $sqlfilters SQL criteria to filter with. Syntax example "(t.code:=:'OrderByWWW')"
58
     *
59
     * @url     GET dictionary/ordering_methods
60
     *
61
     * @return array [List of ordering methods]
62
     *
63
     * @throws RestException 400
64
     */
65
    public function getOrderingMethods($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
66
    {
67
        $list = array();
68
69
        $sql = "SELECT rowid, code, libelle as label, module";
70
        $sql .= " FROM ".MAIN_DB_PREFIX."c_input_method as t";
71
        $sql .= " WHERE t.active = ".$active;
72
        // Add sql filters
73
        if ($sqlfilters)
74
        {
75
            if (!DolibarrApi::_checkFilters($sqlfilters))
76
            {
77
                throw new RestException(400, 'error when validating parameter sqlfilters '.$sqlfilters);
78
            }
79
            $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
80
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
81
        }
82
83
84
        $sql .= $this->db->order($sortfield, $sortorder);
85
86
        if ($limit) {
87
            if ($page < 0) {
88
                $page = 0;
89
            }
90
            $offset = $limit * $page;
91
92
            $sql .= $this->db->plimit($limit, $offset);
93
        }
94
95
        $result = $this->db->query($sql);
96
97
        if ($result) {
98
            $num = $this->db->num_rows($result);
99
            $min = min($num, ($limit <= 0 ? $num : $limit));
100
            for ($i = 0; $i < $min; $i++) {
101
                $list[] = $this->db->fetch_object($result);
102
            }
103
        } else {
104
            throw new RestException(400, $this->db->lasterror());
105
        }
106
107
        return $list;
108
    }
109
110
    /**
111
     * Get the list of payments types.
112
     *
113
     * @param string    $sortfield  Sort field
114
     * @param string    $sortorder  Sort order
115
     * @param int       $limit      Number of items per page
116
     * @param int       $page       Page number {@min 0}
117
     * @param int       $active     Payment type is active or not {@min 0} {@max 1}
118
     * @param string    $sqlfilters SQL criteria to filter with. Syntax example "(t.code:=:'CHQ')"
119
     *
120
     * @url     GET dictionary/payment_types
121
     *
122
     * @return array [List of payment types]
123
     *
124
     * @throws RestException 400
125
     */
126
    public function getPaymentTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
127
    {
128
        $list = array();
129
130
        $sql = "SELECT id, code, type, libelle as label, module";
131
        $sql .= " FROM ".MAIN_DB_PREFIX."c_paiement as t";
132
        $sql .= " WHERE t.entity IN (".getEntity('c_paiement').")";
133
        $sql .= " AND t.active = ".$active;
134
        // Add sql filters
135
        if ($sqlfilters)
136
        {
137
            if (!DolibarrApi::_checkFilters($sqlfilters))
138
            {
139
                throw new RestException(400, 'error when validating parameter sqlfilters '.$sqlfilters);
140
            }
141
              $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
142
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
143
        }
144
145
146
        $sql .= $this->db->order($sortfield, $sortorder);
147
148
        if ($limit) {
149
            if ($page < 0) {
150
                $page = 0;
151
            }
152
            $offset = $limit * $page;
153
154
            $sql .= $this->db->plimit($limit, $offset);
155
        }
156
157
        $result = $this->db->query($sql);
158
159
        if ($result) {
160
            $num = $this->db->num_rows($result);
161
            $min = min($num, ($limit <= 0 ? $num : $limit));
162
            for ($i = 0; $i < $min; $i++) {
163
                $list[] = $this->db->fetch_object($result);
164
            }
165
        } else {
166
            throw new RestException(400, $this->db->lasterror());
167
        }
168
169
        return $list;
170
    }
171
172
    /**
173
     * Get the list of states/provinces.
174
     *
175
     * The names of the states will be translated to the given language if
176
     * the $lang parameter is provided. The value of $lang must be a language
177
     * code supported by Dolibarr, for example 'en_US' or 'fr_FR'.
178
     * The returned list is sorted by state ID.
179
     *
180
     * @param string    $sortfield  Sort field
181
     * @param string    $sortorder  Sort order
182
     * @param int       $limit      Number of items per page
183
     * @param int       $page       Page number (starting from zero)
184
     * @param string    $filter     To filter the countries by name
185
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
186
     * @return array                List of countries
187
     *
188
     * @url     GET dictionary/states
189
     *
190
     * @throws RestException
191
     */
192
    public function getListOfStates($sortfield = "code_departement", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $sqlfilters = '')
193
    {
194
        $list = array();
195
196
        // Note: The filter is not applied in the SQL request because it must
197
        // be applied to the translated names, not to the names in database.
198
        $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_departements as t";
199
        $sql .= " WHERE 1 = 1";
200
        // Add sql filters
201
        if ($sqlfilters)
202
        {
203
            if (!DolibarrApi::_checkFilters($sqlfilters))
204
            {
205
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
206
            }
207
	        $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
208
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
209
        }
210
211
        $sql .= $this->db->order($sortfield, $sortorder);
212
213
        if ($limit) {
214
            if ($page < 0) {
215
                $page = 0;
216
            }
217
            $offset = $limit * $page;
218
219
            $sql .= $this->db->plimit($limit, $offset);
220
        }
221
222
        $result = $this->db->query($sql);
223
224
        if ($result) {
225
            $num = $this->db->num_rows($result);
226
            $min = min($num, ($limit <= 0 ? $num : $limit));
227
            for ($i = 0; $i < $min; $i++) {
228
                $obj = $this->db->fetch_object($result);
229
                $state = new Cstate($this->db);
230
                if ($state->fetch($obj->rowid) > 0) {
231
                    if (empty($filter) || stripos($state->label, $filter) !== false) {
232
                        $list[] = $this->_cleanObjectDatas($state);
233
                    }
234
                }
235
            }
236
        } else {
237
            throw new RestException(503, 'Error when retrieving list of states');
238
        }
239
240
        return $list;
241
    }
242
243
    /**
244
     * Get state by ID.
245
     *
246
     * @param int       $id        ID of state
247
     * @return array 			   Array of cleaned object properties
248
     *
249
     * @url     GET dictionary/states/{id}
250
     *
251
     * @throws RestException
252
     */
253
    public function getStateByID($id)
254
    {
255
        return $this->_fetchCstate($id, '');
256
    }
257
258
    /**
259
     * Get state by Code.
260
     *
261
     * @param string    $code      Code of state
262
     * @return array 			   Array of cleaned object properties
263
     *
264
     * @url     GET dictionary/states/byCode/{code}
265
     *
266
     * @throws RestException
267
     */
268
    public function getStateByCode($code)
269
    {
270
        return $this->_fetchCstate('', $code);
271
    }
272
273
    /**
274
     * Get the list of countries.
275
     *
276
     * The names of the countries will be translated to the given language if
277
     * the $lang parameter is provided. The value of $lang must be a language
278
     * code supported by Dolibarr, for example 'en_US' or 'fr_FR'.
279
     * The returned list is sorted by country ID.
280
     *
281
     * @param string    $sortfield  Sort field
282
     * @param string    $sortorder  Sort order
283
     * @param int       $limit      Number of items per page
284
     * @param int       $page       Page number (starting from zero)
285
     * @param string    $filter     To filter the countries by name
286
     * @param string    $lang       Code of the language the label of the countries must be translated to
287
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
288
     * @return array                List of countries
289
     *
290
     * @url     GET dictionary/countries
291
     *
292
     * @throws RestException
293
     */
294
    public function getListOfCountries($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $lang = '', $sqlfilters = '')
295
    {
296
        $list = array();
297
298
        // Note: The filter is not applied in the SQL request because it must
299
        // be applied to the translated names, not to the names in database.
300
        $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_country as t";
301
        $sql .= " WHERE 1 = 1";
302
        // Add sql filters
303
        if ($sqlfilters)
304
        {
305
            if (!DolibarrApi::_checkFilters($sqlfilters))
306
            {
307
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
308
            }
309
	        $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
310
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
311
        }
312
313
        $sql .= $this->db->order($sortfield, $sortorder);
314
315
        if ($limit) {
316
            if ($page < 0) {
317
                $page = 0;
318
            }
319
            $offset = $limit * $page;
320
321
            $sql .= $this->db->plimit($limit, $offset);
322
        }
323
324
        $result = $this->db->query($sql);
325
326
        if ($result) {
327
            $num = $this->db->num_rows($result);
328
            $min = min($num, ($limit <= 0 ? $num : $limit));
329
            for ($i = 0; $i < $min; $i++) {
330
                $obj = $this->db->fetch_object($result);
331
                $country = new Ccountry($this->db);
332
                if ($country->fetch($obj->rowid) > 0) {
333
                    // Translate the name of the country if needed
334
                    // and then apply the filter if there is one.
335
                    $this->translateLabel($country, $lang, 'Country');
336
337
                    if (empty($filter) || stripos($country->label, $filter) !== false) {
338
                        $list[] = $this->_cleanObjectDatas($country);
339
                    }
340
                }
341
            }
342
        } else {
343
            throw new RestException(503, 'Error when retrieving list of countries');
344
        }
345
346
        return $list;
347
    }
348
349
    /**
350
     * Get country by ID.
351
     *
352
     * @param int       $id        ID of country
353
     * @param string    $lang      Code of the language the name of the
354
     *                             country must be translated to
355
     * @return array 			   Array of cleaned object properties
356
     *
357
     * @url     GET dictionary/countries/{id}
358
     *
359
     * @throws RestException
360
     */
361
    public function getCountryByID($id, $lang = '')
362
    {
363
        return $this->_fetchCcountry($id, '', '', $lang);
364
    }
365
366
    /**
367
     * Get country by Code.
368
     *
369
     * @param string    $code      Code of country
370
     * @param string    $lang      Code of the language the name of the
371
     *                             country must be translated to
372
     * @return array 			   Array of cleaned object properties
373
     *
374
     * @url     GET dictionary/countries/byCode/{code}
375
     *
376
     * @throws RestException
377
     */
378
    public function getCountryByCode($code, $lang = '')
379
    {
380
        return $this->_fetchCcountry('', $code, '', $lang);
381
    }
382
383
    /**
384
     * Get country by Iso.
385
     *
386
     * @param string    $iso       ISO of country
387
     * @param string    $lang      Code of the language the name of the
388
     *                             country must be translated to
389
     * @return array 			   Array of cleaned object properties
390
     *
391
     * @url     GET dictionary/countries/byISO/{iso}
392
     *
393
     * @throws RestException
394
     */
395
    public function getCountryByISO($iso, $lang = '')
396
    {
397
        return $this->_fetchCcountry('', '', $iso, $lang);
398
    }
399
400
    /**
401
    * Get state.
402
    *
403
    * @param int       $id        ID of state
404
    * @param string    $code      Code of state
405
    * @return array 			   Array of cleaned object properties
406
    *
407
    * @throws RestException
408
    */
409
    private function _fetchCstate($id, $code = '')
410
    {
411
        $state = new Cstate($this->db);
412
413
        $result = $state->fetch($id, $code);
414
        if ($result < 0) {
415
            throw new RestException(503, 'Error when retrieving state : '.$state->error);
416
        } elseif ($result == 0) {
417
            throw new RestException(404, 'State not found');
418
        }
419
420
        return $this->_cleanObjectDatas($state);
421
    }
422
423
    /**
424
    * Get country.
425
    *
426
    * @param int       $id        ID of country
427
    * @param string    $code      Code of country
428
    * @param string    $iso       ISO of country
429
    * @param string    $lang      Code of the language the name of the
430
    *                             country must be translated to
431
    * @return array 			   Array of cleaned object properties
432
    *
433
    * @throws RestException
434
    */
435
    private function _fetchCcountry($id, $code = '', $iso = '', $lang = '')
436
    {
437
        $country = new Ccountry($this->db);
438
439
        $result = $country->fetch($id, $code, $iso);
440
        if ($result < 0) {
441
            throw new RestException(503, 'Error when retrieving country : '.$country->error);
442
        } elseif ($result == 0) {
443
            throw new RestException(404, 'country not found');
444
        }
445
446
        $this->translateLabel($country, $lang, 'Country');
447
448
        return $this->_cleanObjectDatas($country);
449
    }
450
451
    /**
452
     * Get the list of delivery times.
453
     *
454
     * @param string    $sortfield  Sort field
455
     * @param string    $sortorder  Sort order
456
     * @param int       $limit      Number of items per page
457
     * @param int       $page       Page number {@min 0}
458
     * @param int       $active     Delivery times is active or not {@min 0} {@max 1}
459
     * @param string    $sqlfilters SQL criteria to filter with.
460
     *
461
     * @url     GET dictionary/availability
462
     *
463
     * @return array [List of availability]
464
     *
465
     * @throws RestException 400
466
     */
467
    public function getAvailability($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
468
    {
469
        $list = array();
470
471
        $sql = "SELECT rowid, code, label";
472
        $sql .= " FROM ".MAIN_DB_PREFIX."c_availability as t";
473
        $sql .= " WHERE t.active = ".$active;
474
        // Add sql filters
475
        if ($sqlfilters)
476
        {
477
            if (!DolibarrApi::_checkFilters($sqlfilters))
478
            {
479
                throw new RestException(400, 'error when validating parameter sqlfilters '.$sqlfilters);
480
            }
481
                  $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
482
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
483
        }
484
485
486
        $sql .= $this->db->order($sortfield, $sortorder);
487
488
        if ($limit) {
489
            if ($page < 0) {
490
                $page = 0;
491
            }
492
            $offset = $limit * $page;
493
494
            $sql .= $this->db->plimit($limit, $offset);
495
        }
496
497
        $result = $this->db->query($sql);
498
499
        if ($result) {
500
            $num = $this->db->num_rows($result);
501
            $min = min($num, ($limit <= 0 ? $num : $limit));
502
            for ($i = 0; $i < $min; $i++) {
503
                $list[] = $this->db->fetch_object($result);
504
            }
505
        } else {
506
            throw new RestException(400, $this->db->lasterror());
507
        }
508
509
        return $list;
510
    }
511
512
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
513
    /**
514
     * Clean sensible object datas
515
     *
516
     * @param object    $object    Object to clean
517
     * @return array 				Array of cleaned object properties
518
     */
519
    protected function _cleanObjectDatas($object)
520
    {
521
        // phpcs:enable
522
        $object = parent::_cleanObjectDatas($object);
523
524
        unset($object->error);
525
        unset($object->errors);
526
527
        return $object;
528
    }
529
530
    /**
531
     * Translate the name of the object to the given language.
532
     *
533
     * @param object   $object    Object with label to translate
534
     * @param string   $lang      Code of the language the name of the object must be translated to
535
     * @param string   $prefix 	  Prefix for translation key
536
     *
537
     * @return void
538
     */
539
    private function translateLabel($object, $lang, $prefix = 'Country')
540
    {
541
        if (!empty($lang)) {
542
            // Load the translations if this is a new language.
543
            if ($this->translations == null || $this->translations->getDefaultLang() !== $lang) {
544
                global $conf;
545
                $this->translations = new Translate('', $conf);
546
                $this->translations->setDefaultLang($lang);
547
                $this->translations->load('dict');
548
            }
549
            if ($object->code) {
550
                $key = $prefix.$object->code;
551
552
                $translation = $this->translations->trans($key);
553
                if ($translation != $key) {
554
                    $object->label = html_entity_decode($translation);
555
                }
556
            }
557
        }
558
    }
559
560
    /**
561
     * Get the list of shipment methods.
562
     *
563
     * @param string    $sortfield  Sort field
564
     * @param string    $sortorder  Sort order
565
     * @param int       $limit      Number of items per page
566
     * @param int       $page       Page number (starting from zero)
567
     * @param int       $active     Payment term is active or not {@min 0} {@max 1}
568
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
569
     *
570
     * @return array List of shipment methods
571
     *
572
     * @url     GET dictionary/shipment_methods
573
     *
574
     * @throws RestException
575
     */
576
    public function getListOfShipmentMethods($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
577
    {
578
        $list = array();
579
        $sql = "SELECT t.rowid, t.code, t.libelle, t.description, t.tracking";
580
        $sql .= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as t";
581
        $sql .= " WHERE t.active = ".$active;
582
        // Add sql filters
583
        if ($sqlfilters)
584
        {
585
            if (!DolibarrApi::_checkFilters($sqlfilters))
586
            {
587
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
588
            }
589
            $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
590
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
591
        }
592
593
594
        $sql .= $this->db->order($sortfield, $sortorder);
595
596
        if ($limit) {
597
            if ($page < 0) {
598
                $page = 0;
599
            }
600
            $offset = $limit * $page;
601
602
            $sql .= $this->db->plimit($limit, $offset);
603
        }
604
605
        $result = $this->db->query($sql);
606
607
        if ($result) {
608
            $num = $this->db->num_rows($result);
609
            $min = min($num, ($limit <= 0 ? $num : $limit));
610
            for ($i = 0; $i < $min; $i++) {
611
                $list[] = $this->db->fetch_object($result);
612
            }
613
        } else {
614
            throw new RestException(503, 'Error when retrieving list of shipment methods : '.$this->db->lasterror());
615
        }
616
617
        return $list;
618
    }
619
620
    /**
621
     * Get the list of events types.
622
     *
623
     * @param string    $sortfield  Sort field
624
     * @param string    $sortorder  Sort order
625
     * @param int       $limit      Number of items per page
626
     * @param int       $page       Page number (starting from zero)
627
     * @param string    $type       To filter on type of event
628
     * @param string    $module     To filter on module events
629
     * @param int       $active     Event's type is active or not {@min 0} {@max 1}
630
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
631
     * @return array				List of events types
632
     *
633
     * @url     GET dictionary/event_types
634
     *
635
     * @throws RestException
636
     */
637
    public function getListOfEventTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $active = 1, $sqlfilters = '')
638
    {
639
        $list = array();
640
641
        $sql = "SELECT id, code, type, libelle as label, module";
642
        $sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm as t";
643
        $sql .= " WHERE t.active = ".$active;
644
        if ($type) $sql .= " AND t.type LIKE '%".$this->db->escape($type)."%'";
645
        if ($module)    $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
646
        // Add sql filters
647
        if ($sqlfilters)
648
        {
649
            if (!DolibarrApi::_checkFilters($sqlfilters))
650
            {
651
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
652
            }
653
	        $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
654
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
655
        }
656
657
658
        $sql .= $this->db->order($sortfield, $sortorder);
659
660
        if ($limit) {
661
            if ($page < 0) {
662
                $page = 0;
663
            }
664
            $offset = $limit * $page;
665
666
            $sql .= $this->db->plimit($limit, $offset);
667
        }
668
669
        $result = $this->db->query($sql);
670
671
        if ($result) {
672
            $num = $this->db->num_rows($result);
673
            $min = min($num, ($limit <= 0 ? $num : $limit));
674
            for ($i = 0; $i < $min; $i++) {
675
                $list[] = $this->db->fetch_object($result);
676
            }
677
        } else {
678
            throw new RestException(503, 'Error when retrieving list of events types : '.$this->db->lasterror());
679
        }
680
681
        return $list;
682
    }
683
684
685
    /**
686
     * Get the list of Expense Report types.
687
     *
688
     * @param string    $sortfield  Sort field
689
     * @param string    $sortorder  Sort order
690
     * @param int       $limit      Number of items per page
691
     * @param int       $page       Page number (starting from zero)
692
     * @param string    $module     To filter on module
693
     * @param int       $active     Event's type is active or not {@min 0} {@max 1}
694
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
695
     * @return array				List of expense report types
696
     *
697
     * @url     GET dictionary/expensereport_types
698
     *
699
     * @throws RestException
700
     */
701
    public function getListOfExpenseReportsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $module = '', $active = 1, $sqlfilters = '')
702
    {
703
    	$list = array();
704
705
    	$sql = "SELECT id, code, label, accountancy_code, active, module, position";
706
    	$sql .= " FROM ".MAIN_DB_PREFIX."c_type_fees as t";
707
    	$sql .= " WHERE t.active = ".$active;
708
    	if ($module)    $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
709
    	// Add sql filters
710
    	if ($sqlfilters)
711
    	{
712
    		if (!DolibarrApi::_checkFilters($sqlfilters))
713
    		{
714
    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
715
    		}
716
    		$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
717
    		$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
718
    	}
719
720
721
    	$sql .= $this->db->order($sortfield, $sortorder);
722
723
    	if ($limit) {
724
    		if ($page < 0) {
725
    			$page = 0;
726
    		}
727
    		$offset = $limit * $page;
728
729
    		$sql .= $this->db->plimit($limit, $offset);
730
    	}
731
732
    	$result = $this->db->query($sql);
733
734
    	if ($result) {
735
    		$num = $this->db->num_rows($result);
736
    		$min = min($num, ($limit <= 0 ? $num : $limit));
737
    		for ($i = 0; $i < $min; $i++) {
738
    			$list[] = $this->db->fetch_object($result);
739
    		}
740
    	} else {
741
    		throw new RestException(503, 'Error when retrieving list of expense report types : '.$this->db->lasterror());
742
    	}
743
744
    	return $list;
745
    }
746
747
748
    /**
749
     * Get the list of contacts types.
750
     *
751
     * @param string    $sortfield  Sort field
752
     * @param string    $sortorder  Sort order
753
     * @param int       $limit      Number of items per page
754
     * @param int       $page       Page number (starting from zero)
755
     * @param string    $type       To filter on type of contact
756
     * @param string    $module     To filter on module contacts
757
     * @param int       $active     Contact's type is active or not {@min 0} {@max 1}
758
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
759
     * @return array	  List of Contacts types
760
     *
761
     * @url     GET dictionary/contact_types
762
     *
763
     * @throws RestException
764
     */
765
    public function getListOfContactTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $active = 1, $sqlfilters = '')
766
    {
767
        $list = array();
768
769
        $sql = "SELECT rowid, code, element as type, libelle as label, source, module, position";
770
        $sql .= " FROM ".MAIN_DB_PREFIX."c_type_contact as t";
771
        $sql .= " WHERE t.active = ".$active;
772
        if ($type) $sql .= " AND type LIKE '%".$this->db->escape($type)."%'";
773
        if ($module)    $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
774
        // Add sql filters
775
        if ($sqlfilters)
776
        {
777
            if (!DolibarrApi::_checkFilters($sqlfilters))
778
            {
779
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
780
            }
781
	        $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
782
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
783
        }
784
785
786
        $sql .= $this->db->order($sortfield, $sortorder);
787
788
        if ($limit) {
789
            if ($page < 0) {
790
                $page = 0;
791
            }
792
            $offset = $limit * $page;
793
794
            $sql .= $this->db->plimit($limit, $offset);
795
        }
796
797
        $result = $this->db->query($sql);
798
799
        if ($result) {
800
            $num = $this->db->num_rows($result);
801
            $min = min($num, ($limit <= 0 ? $num : $limit));
802
            for ($i = 0; $i < $min; $i++) {
803
                $list[] = $this->db->fetch_object($result);
804
            }
805
        } else {
806
            throw new RestException(503, 'Error when retrieving list of contacts types : '.$this->db->lasterror());
807
        }
808
809
        return $list;
810
    }
811
812
    /**
813
     * Get the list of civilities.
814
     *
815
     * @param string    $sortfield  Sort field
816
     * @param string    $sortorder  Sort order
817
     * @param int       $limit      Number of items per page
818
     * @param int       $page       Page number (starting from zero)
819
     * @param string    $module     To filter on module events
820
     * @param int       $active     Civility is active or not {@min 0} {@max 1}
821
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
822
     * @return array		List of civility types
823
     *
824
     * @url     GET dictionary/civilities
825
     *
826
     * @throws RestException
827
     */
828
    public function getListOfCivilities($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $module = '', $active = 1, $sqlfilters = '')
829
    {
830
        $list = array();
831
832
        $sql = "SELECT rowid, code, label, module";
833
        $sql .= " FROM ".MAIN_DB_PREFIX."c_civility as t";
834
        $sql .= " WHERE t.active = ".$active;
835
        if ($module)    $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
836
        // Add sql filters
837
        if ($sqlfilters)
838
        {
839
            if (!DolibarrApi::_checkFilters($sqlfilters))
840
            {
841
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
842
            }
843
	        $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
844
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
845
        }
846
847
848
        $sql .= $this->db->order($sortfield, $sortorder);
849
850
        if ($limit) {
851
            if ($page < 0) {
852
                $page = 0;
853
            }
854
            $offset = $limit * $page;
855
856
            $sql .= $this->db->plimit($limit, $offset);
857
        }
858
859
        $result = $this->db->query($sql);
860
861
        if ($result) {
862
            $num = $this->db->num_rows($result);
863
            $min = min($num, ($limit <= 0 ? $num : $limit));
864
            for ($i = 0; $i < $min; $i++) {
865
                $list[] = $this->db->fetch_object($result);
866
            }
867
        } else {
868
            throw new RestException(503, 'Error when retrieving list of civility : '.$this->db->lasterror());
869
        }
870
871
        return $list;
872
    }
873
874
    /**
875
     * Get the list of currencies.
876
     *
877
     * @param int       $multicurrency  Multicurrency rates (0: no multicurrency, 1: last rate, 2: all rates) {@min 0} {@max 2}
878
     * @param string    $sortfield  Sort field
879
     * @param string    $sortorder  Sort order
880
     * @param int       $limit      Number of items per page
881
     * @param int       $page       Page number (starting from zero)
882
     * @param int       $active     Payment term is active or not {@min 0} {@max 1}
883
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
884
     * @return array				List of currencies
885
     *
886
     * @url     GET dictionary/currencies
887
     *
888
     * @throws RestException
889
     */
890
    public function getListOfCurrencies($multicurrency = 0, $sortfield = "code_iso", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
891
    {
892
        $list = array();
893
        $sql = "SELECT t.code_iso, t.label, t.unicode";
894
        if (!empty($multicurrency)) $sql .= " , cr.date_sync, cr.rate ";
895
        $sql .= " FROM ".MAIN_DB_PREFIX."c_currencies as t";
896
        if (!empty($multicurrency)) {
897
            $sql .= " JOIN ".MAIN_DB_PREFIX."multicurrency as m ON m.code=t.code_iso";
898
            $sql .= " JOIN ".MAIN_DB_PREFIX."multicurrency_rate as cr ON (m.rowid = cr.fk_multicurrency)";
899
        }
900
        $sql .= " WHERE t.active = ".$active;
901
        if (!empty($multicurrency)) {
902
            $sql .= " AND m.entity IN (".getEntity('multicurrency').")";
903
            if (!empty($multicurrency) && $multicurrency != 2) {
904
                $sql .= " AND cr.date_sync = (SELECT MAX(cr2.date_sync) FROM ".MAIN_DB_PREFIX."multicurrency_rate AS cr2 WHERE cr2.fk_multicurrency = m.rowid)";
905
            }
906
        }
907
908
        // Add sql filters
909
        if ($sqlfilters)
910
        {
911
            if (!DolibarrApi::_checkFilters($sqlfilters))
912
            {
913
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
914
            }
915
	        $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
916
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
917
        }
918
919
920
        $sql .= $this->db->order($sortfield, $sortorder);
921
922
        if ($limit) {
923
            if ($page < 0) {
924
                $page = 0;
925
            }
926
            $offset = $limit * $page;
927
928
            $sql .= $this->db->plimit($limit, $offset);
929
        }
930
931
        $result = $this->db->query($sql);
932
933
        if ($result) {
934
            $num = $this->db->num_rows($result);
935
            $min = min($num, ($limit <= 0 ? $num : $limit));
936
            for ($i = 0; $i < $min; $i++) {
937
                $list[] = $this->db->fetch_object($result);
938
            }
939
        } else {
940
            throw new RestException(503, 'Error when retrieving list of currency : '.$this->db->lasterror());
941
        }
942
943
        return $list;
944
    }
945
946
    /**
947
     * Get the list of extra fields.
948
     *
949
     * @param string	$sortfield	Sort field
950
     * @param string	$sortorder	Sort order
951
     * @param string    $type       Type of element ('adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...)
952
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.label:like:'SO-%')"
953
     * @return array				List of extra fields
954
     *
955
     * @url     GET extrafields
956
     *
957
     * @throws RestException
958
     */
959
    public function getListOfExtrafields($sortfield = "t.pos", $sortorder = 'ASC', $type = '', $sqlfilters = '')
960
    {
961
        $list = array();
962
963
        if ($type == 'thirdparty') $type = 'societe';
964
        if ($type == 'contact') $type = 'socpeople';
965
966
        $sql = "SELECT t.rowid, t.name, t.label, t.type, t.size, t.elementtype, t.fieldunique, t.fieldrequired, t.param, t.pos, t.alwayseditable, t.perms, t.list, t.fielddefault, t.fieldcomputed";
967
        $sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
968
        $sql .= " WHERE t.entity IN (".getEntity('extrafields').")";
969
        if (!empty($type)) $sql .= " AND t.elementtype = '".$this->db->escape($type)."'";
970
        // Add sql filters
971
        if ($sqlfilters)
972
        {
973
        	if (!DolibarrApi::_checkFilters($sqlfilters))
974
        	{
975
        		throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
976
        	}
977
        	$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
978
        	$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
979
        }
980
981
        $sql .= $this->db->order($sortfield, $sortorder);
982
983
        $resql = $this->db->query($sql);
984
        if ($resql)
985
        {
986
        	if ($this->db->num_rows($resql))
987
        	{
988
        		while ($tab = $this->db->fetch_object($resql))
989
        		{
990
        			// New usage
991
        			$list[$tab->elementtype][$tab->name]['type'] = $tab->type;
992
        			$list[$tab->elementtype][$tab->name]['label'] = $tab->label;
993
        			$list[$tab->elementtype][$tab->name]['size'] = $tab->size;
994
        			$list[$tab->elementtype][$tab->name]['elementtype'] = $tab->elementtype;
995
        			$list[$tab->elementtype][$tab->name]['default'] = $tab->fielddefault;
996
        			$list[$tab->elementtype][$tab->name]['computed'] = $tab->fieldcomputed;
997
        			$list[$tab->elementtype][$tab->name]['unique'] = $tab->fieldunique;
998
        			$list[$tab->elementtype][$tab->name]['required'] = $tab->fieldrequired;
999
        			$list[$tab->elementtype][$tab->name]['param'] = ($tab->param ? unserialize($tab->param) : '');
1000
        			$list[$tab->elementtype][$tab->name]['pos'] = $tab->pos;
1001
        			$list[$tab->elementtype][$tab->name]['alwayseditable'] = $tab->alwayseditable;
1002
        			$list[$tab->elementtype][$tab->name]['perms'] = $tab->perms;
1003
        			$list[$tab->elementtype][$tab->name]['list'] = $tab->list;
1004
        		}
1005
        	}
1006
        } else {
1007
            throw new RestException(503, 'Error when retrieving list of extra fields : '.$this->db->lasterror());
1008
        }
1009
1010
        if (!count($list))
1011
        {
1012
        	throw new RestException(404, 'No extrafield found');
1013
        }
1014
1015
        return $list;
1016
    }
1017
1018
1019
    /**
1020
     * Get the list of towns.
1021
     *
1022
     * @param string    $sortfield  Sort field
1023
     * @param string    $sortorder  Sort order
1024
     * @param int       $limit      Number of items per page
1025
     * @param int       $page       Page number (starting from zero)
1026
     * @param string    $zipcode    To filter on zipcode
1027
     * @param string    $town       To filter on city name
1028
     * @param int       $active     Payment term is active or not {@min 0} {@max 1}
1029
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
1030
     * @return array				List of towns
1031
     *
1032
     * @url     GET dictionary/towns
1033
     *
1034
     * @throws RestException
1035
     */
1036
    public function getListOfTowns($sortfield = "zip,town", $sortorder = 'ASC', $limit = 100, $page = 0, $zipcode = '', $town = '', $active = 1, $sqlfilters = '')
1037
    {
1038
        $list = array();
1039
1040
        $sql = "SELECT rowid AS id, zip, town, fk_county, fk_pays AS fk_country";
1041
        $sql .= " FROM ".MAIN_DB_PREFIX."c_ziptown as t";
1042
        $sql .= " AND t.active = ".$active;
1043
        if ($zipcode) $sql .= " AND t.zip LIKE '%".$this->db->escape($zipcode)."%'";
1044
        if ($town)    $sql .= " AND t.town LIKE '%".$this->db->escape($town)."%'";
1045
        // Add sql filters
1046
        if ($sqlfilters)
1047
        {
1048
            if (!DolibarrApi::_checkFilters($sqlfilters))
1049
            {
1050
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
1051
            }
1052
	        $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
1053
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
1054
        }
1055
1056
1057
        $sql .= $this->db->order($sortfield, $sortorder);
1058
1059
        if ($limit) {
1060
            if ($page < 0) {
1061
                $page = 0;
1062
            }
1063
            $offset = $limit * $page;
1064
1065
            $sql .= $this->db->plimit($limit, $offset);
1066
        }
1067
1068
        $result = $this->db->query($sql);
1069
1070
        if ($result) {
1071
            $num = $this->db->num_rows($result);
1072
            $min = min($num, ($limit <= 0 ? $num : $limit));
1073
            for ($i = 0; $i < $min; $i++) {
1074
                $list[] = $this->db->fetch_object($result);
1075
            }
1076
        } else {
1077
            throw new RestException(503, 'Error when retrieving list of towns : '.$this->db->lasterror());
1078
        }
1079
1080
        return $list;
1081
    }
1082
1083
    /**
1084
     * Get the list of payments terms.
1085
     *
1086
     * @param string    $sortfield  Sort field
1087
     * @param string    $sortorder  Sort order
1088
     * @param int       $limit      Number of items per page
1089
     * @param int       $page       Page number {@min 0}
1090
     * @param int       $active     Payment term is active or not {@min 0} {@max 1}
1091
     * @param string    $sqlfilters SQL criteria to filter. Syntax example "(t.code:=:'CHQ')"
1092
     *
1093
     * @url     GET dictionary/payment_terms
1094
     *
1095
     * @return array List of payment terms
1096
     *
1097
     * @throws RestException 400
1098
     */
1099
    public function getPaymentTerms($sortfield = "sortorder", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1100
    {
1101
        $list = array();
1102
1103
        $sql = "SELECT rowid as id, code, sortorder, libelle as label, libelle_facture as descr, type_cdr, nbjour, decalage, module";
1104
        $sql .= " FROM ".MAIN_DB_PREFIX."c_payment_term as t";
1105
        $sql .= " WHERE t.entity IN (".getEntity('c_payment_term').")";
1106
        $sql .= " AND t.active = ".$active;
1107
        // Add sql filters
1108
        if ($sqlfilters)
1109
        {
1110
            if (!DolibarrApi::_checkFilters($sqlfilters))
1111
            {
1112
                throw new RestException(400, 'Error when validating parameter sqlfilters '.$sqlfilters);
1113
            }
1114
                $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
1115
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
1116
        }
1117
1118
1119
        $sql .= $this->db->order($sortfield, $sortorder);
1120
1121
        if ($limit) {
1122
            if ($page < 0) {
1123
                $page = 0;
1124
            }
1125
            $offset = $limit * $page;
1126
1127
            $sql .= $this->db->plimit($limit, $offset);
1128
        }
1129
1130
        $result = $this->db->query($sql);
1131
1132
        if ($result) {
1133
            $num = $this->db->num_rows($result);
1134
            $min = min($num, ($limit <= 0 ? $num : $limit));
1135
            for ($i = 0; $i < $min; $i++) {
1136
                $list[] = $this->db->fetch_object($result);
1137
            }
1138
        } else {
1139
            throw new RestException(400, $this->db->lasterror());
1140
        }
1141
1142
        return $list;
1143
    }
1144
1145
    /**
1146
     * Get the list of shipping methods.
1147
     *
1148
     * @param int       $limit      Number of items per page
1149
     * @param int       $page       Page number {@min 0}
1150
     * @param int       $active     Shipping methodsm is active or not {@min 0} {@max 1}
1151
     * @param string    $sqlfilters SQL criteria to filter. Syntax example "(t.code:=:'CHQ')"
1152
     *
1153
     * @url     GET dictionary/shipping_methods
1154
     *
1155
     * @return array List of shipping methods
1156
     *
1157
     * @throws RestException 400
1158
     */
1159
    public function getShippingModes($limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1160
    {
1161
        $list = array();
1162
1163
        $sql = "SELECT rowid as id, code, libelle as label, description, tracking, module";
1164
        $sql .= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as t";
1165
        $sql .= " WHERE t.entity IN (".getEntity('c_shipment_mode').")";
1166
        $sql .= " AND t.active = ".$active;
1167
        // Add sql filters
1168
        if ($sqlfilters)
1169
        {
1170
            if (!DolibarrApi::_checkFilters($sqlfilters))
1171
            {
1172
                throw new RestException(400, 'Error when validating parameter sqlfilters '.$sqlfilters);
1173
            }
1174
                $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
1175
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
1176
        }
1177
1178
1179
        //$sql.= $this->db->order($sortfield, $sortorder);
1180
1181
        if ($limit) {
1182
            if ($page < 0) {
1183
                $page = 0;
1184
            }
1185
            $offset = $limit * $page;
1186
1187
            $sql .= $this->db->plimit($limit, $offset);
1188
        }
1189
1190
        $result = $this->db->query($sql);
1191
1192
        if ($result) {
1193
            $num = $this->db->num_rows($result);
1194
            $min = min($num, ($limit <= 0 ? $num : $limit));
1195
            for ($i = 0; $i < $min; $i++) {
1196
                $list[] = $this->db->fetch_object($result);
1197
            }
1198
        } else {
1199
            throw new RestException(400, $this->db->lasterror());
1200
        }
1201
1202
        return $list;
1203
    }
1204
1205
    /**
1206
     * Get the list of measuring units.
1207
     *
1208
     * @param string    $sortfield  Sort field
1209
     * @param string    $sortorder  Sort order
1210
     * @param int       $limit      Number of items per page
1211
     * @param int       $page       Page number (starting from zero)
1212
     * @param int       $active     Measuring unit is active or not {@min 0} {@max 1}
1213
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
1214
     * @return array				List of measuring unit
1215
     *
1216
     * @url     GET dictionary/units
1217
     *
1218
     * @throws RestException
1219
     */
1220
    public function getListOfMeasuringUnits($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1221
    {
1222
        $list = array();
1223
        //TODO link with multicurrency module
1224
        $sql = "SELECT t.rowid, t.code, t.label,t.short_label, t.active, t.scale, t.unit_type";
1225
        $sql .= " FROM ".MAIN_DB_PREFIX."c_units as t";
1226
        $sql .= " WHERE t.active = ".$active;
1227
        // Add sql filters
1228
        if ($sqlfilters)
1229
        {
1230
            if (!DolibarrApi::_checkFilters($sqlfilters))
1231
            {
1232
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
1233
            }
1234
	        $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
1235
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
1236
        }
1237
1238
1239
        $sql .= $this->db->order($sortfield, $sortorder);
1240
1241
        if ($limit) {
1242
            if ($page < 0) {
1243
                $page = 0;
1244
            }
1245
            $offset = $limit * $page;
1246
1247
            $sql .= $this->db->plimit($limit, $offset);
1248
        }
1249
1250
        $result = $this->db->query($sql);
1251
1252
        if ($result) {
1253
            $num = $this->db->num_rows($result);
1254
            $min = min($num, ($limit <= 0 ? $num : $limit));
1255
            for ($i = 0; $i < $min; $i++) {
1256
                $list[] = $this->db->fetch_object($result);
1257
            }
1258
        } else {
1259
            throw new RestException(503, 'Error when retrieving list of measuring units: '.$this->db->lasterror());
1260
        }
1261
1262
        return $list;
1263
    }
1264
1265
    /**
1266
     * Get the list of social networks.
1267
     *
1268
     * @param string    $sortfield  Sort field
1269
     * @param string    $sortorder  Sort order
1270
     * @param int       $limit      Number of items per page
1271
     * @param int       $page       Page number (starting from zero)
1272
     * @param int       $active     Social network is active or not {@min 0} {@max 1}
1273
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
1274
     * @return array				List of social networks
1275
     *
1276
     * @url     GET dictionary/socialnetworks
1277
     *
1278
     * @throws RestException
1279
     */
1280
    public function getListOfsocialNetworks($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1281
    {
1282
        global $conf;
1283
1284
        if (empty($conf->socialnetworks->enabled)) {
1285
            throw new RestException(400, 'API not available: this dictionary is not enabled by setup');
1286
        }
1287
1288
		$list = array();
1289
        //TODO link with multicurrency module
1290
        $sql = "SELECT t.rowid, t.entity, t.code, t.label, t.url, t.icon, t.active";
1291
        $sql .= " FROM ".MAIN_DB_PREFIX."c_socialnetworks as t";
1292
        $sql .= " WHERE t.entity IN (".getEntity('c_socialnetworks').")";
1293
        $sql .= " AND t.active = ".$active;
1294
        // Add sql filters
1295
        if ($sqlfilters)
1296
        {
1297
            if (!DolibarrApi::_checkFilters($sqlfilters))
1298
            {
1299
                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
1300
            }
1301
	        $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
1302
            $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
1303
        }
1304
1305
1306
        $sql .= $this->db->order($sortfield, $sortorder);
1307
1308
        if ($limit) {
1309
            if ($page < 0) {
1310
                $page = 0;
1311
            }
1312
            $offset = $limit * $page;
1313
1314
            $sql .= $this->db->plimit($limit, $offset);
1315
        }
1316
1317
        $result = $this->db->query($sql);
1318
1319
        if ($result) {
1320
            $num = $this->db->num_rows($result);
1321
            $min = min($num, ($limit <= 0 ? $num : $limit));
1322
            for ($i = 0; $i < $min; $i++) {
1323
                $list[] = $this->db->fetch_object($result);
1324
            }
1325
        } else {
1326
            throw new RestException(503, 'Error when retrieving list of social networks: '.$this->db->lasterror());
1327
        }
1328
1329
        return $list;
1330
    }
1331
1332
     /**
1333
     * Get the list of tickets categories.
1334
     *
1335
     * @param string    $sortfield  Sort field
1336
     * @param string    $sortorder  Sort order
1337
     * @param int       $limit      Number of items per page
1338
     * @param int       $page       Page number (starting from zero)
1339
     * @param int       $active     Payment term is active or not {@min 0} {@max 1}
1340
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
1341
     * @return array				List of ticket categories
1342
     *
1343
     * @url     GET dictionary/ticket_categories
1344
     *
1345
     * @throws RestException
1346
     */
1347
    public function getTicketsCategories($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1348
    {
1349
    	$list = array();
1350
1351
    	$sql = "SELECT rowid, code, pos,  label, use_default, description";
1352
    	$sql .= " FROM ".MAIN_DB_PREFIX."c_ticket_category as t";
1353
        $sql .= " WHERE t.active = ".$active;
1354
    	// Add sql filters
1355
    	if ($sqlfilters)
1356
    	{
1357
    		if (!DolibarrApi::_checkFilters($sqlfilters))
1358
    		{
1359
    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
1360
    		}
1361
    		$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
1362
    		$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
1363
    	}
1364
1365
1366
    	$sql .= $this->db->order($sortfield, $sortorder);
1367
1368
    	if ($limit) {
1369
    		if ($page < 0) {
1370
    			$page = 0;
1371
    		}
1372
    		$offset = $limit * $page;
1373
1374
    		$sql .= $this->db->plimit($limit, $offset);
1375
    	}
1376
1377
    	$result = $this->db->query($sql);
1378
1379
    	if ($result) {
1380
    		$num = $this->db->num_rows($result);
1381
    		$min = min($num, ($limit <= 0 ? $num : $limit));
1382
    		for ($i = 0; $i < $min; $i++) {
1383
    			$list[] = $this->db->fetch_object($result);
1384
    		}
1385
    	} else {
1386
    		throw new RestException(503, 'Error when retrieving list of ticket categories : '.$this->db->lasterror());
1387
    	}
1388
1389
    	return $list;
1390
    }
1391
1392
    /**
1393
     * Get the list of tickets severity.
1394
     *
1395
     * @param string    $sortfield  Sort field
1396
     * @param string    $sortorder  Sort order
1397
     * @param int       $limit      Number of items per page
1398
     * @param int       $page       Page number (starting from zero)
1399
     * @param int       $active     Payment term is active or not {@min 0} {@max 1}
1400
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
1401
     * @return array				List of ticket severities
1402
     *
1403
     * @url     GET dictionary/ticket_severities
1404
     *
1405
     * @throws RestException
1406
     */
1407
    public function getTicketsSeverities($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1408
    {
1409
    	$list = array();
1410
1411
    	$sql = "SELECT rowid, code, pos,  label, use_default, color, description";
1412
    	$sql .= " FROM ".MAIN_DB_PREFIX."c_ticket_severity as t";
1413
        $sql .= " WHERE t.active = ".$active;
1414
    	// Add sql filters
1415
    	if ($sqlfilters)
1416
    	{
1417
    		if (!DolibarrApi::_checkFilters($sqlfilters))
1418
    		{
1419
    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
1420
    		}
1421
    		$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
1422
    		$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
1423
    	}
1424
1425
1426
    	$sql .= $this->db->order($sortfield, $sortorder);
1427
1428
    	if ($limit) {
1429
    		if ($page < 0) {
1430
    			$page = 0;
1431
    		}
1432
    		$offset = $limit * $page;
1433
1434
    		$sql .= $this->db->plimit($limit, $offset);
1435
    	}
1436
1437
    	$result = $this->db->query($sql);
1438
1439
    	if ($result) {
1440
    		$num = $this->db->num_rows($result);
1441
    		$min = min($num, ($limit <= 0 ? $num : $limit));
1442
    		for ($i = 0; $i < $min; $i++) {
1443
    			$list[] = $this->db->fetch_object($result);
1444
    		}
1445
    	} else {
1446
    		throw new RestException(503, 'Error when retrieving list of ticket severities : '.$this->db->lasterror());
1447
    	}
1448
1449
    	return $list;
1450
    }
1451
1452
    /**
1453
     * Get the list of tickets types.
1454
     *
1455
     * @param string    $sortfield  Sort field
1456
     * @param string    $sortorder  Sort order
1457
     * @param int       $limit      Number of items per page
1458
     * @param int       $page       Page number (starting from zero)
1459
     * @param int       $active     Payment term is active or not {@min 0} {@max 1}
1460
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
1461
     * @return array				List of ticket types
1462
     *
1463
     * @url     GET dictionary/ticket_types
1464
     *
1465
     * @throws RestException
1466
     */
1467
    public function getTicketsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1468
    {
1469
    	$list = array();
1470
1471
    	$sql = "SELECT rowid, code, pos,  label, use_default, description";
1472
    	$sql .= " FROM ".MAIN_DB_PREFIX."c_ticket_type as t";
1473
        $sql .= " WHERE t.active = ".(int) $active;
1474
    	// if ($type) $sql .= " AND t.type LIKE '%".$this->db->escape($type)."%'";
1475
    	// if ($module)    $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
1476
    	// Add sql filters
1477
    	if ($sqlfilters)
1478
    	{
1479
    		if (!DolibarrApi::_checkFilters($sqlfilters))
1480
    		{
1481
    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
1482
    		}
1483
    		$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
1484
    		$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
1485
    	}
1486
1487
1488
    	$sql .= $this->db->order($sortfield, $sortorder);
1489
1490
    	if ($limit) {
1491
    		if ($page < 0) {
1492
    			$page = 0;
1493
    		}
1494
    		$offset = $limit * $page;
1495
1496
    		$sql .= $this->db->plimit($limit, $offset);
1497
    	}
1498
1499
    	$result = $this->db->query($sql);
1500
1501
    	if ($result) {
1502
    		$num = $this->db->num_rows($result);
1503
    		$min = min($num, ($limit <= 0 ? $num : $limit));
1504
    		for ($i = 0; $i < $min; $i++) {
1505
    			$list[] = $this->db->fetch_object($result);
1506
    		}
1507
    	} else {
1508
    		throw new RestException(503, 'Error when retrieving list of ticket types : '.$this->db->lasterror());
1509
    	}
1510
1511
    	return $list;
1512
    }
1513
1514
    /**
1515
     * Get properties of company
1516
     *
1517
     * @url	GET /company
1518
     *
1519
     * @return  array|mixed Data without useless information
1520
     *
1521
     */
1522
    public function getCompany()
1523
    {
1524
        global $mysoc;
1525
1526
        return $this->_cleanObjectDatas($mysoc);
1527
    }
1528
1529
1530
    /**
1531
     * Get value of a setup variables
1532
     *
1533
     * Note that conf variables that stores security key or password hashes can't be loaded with API.
1534
     *
1535
     * @param	string			$constantname	Name of conf variable to get
1536
     * @return  array|mixed 				Data without useless information
1537
     *
1538
     * @url     GET conf/{constantname}
1539
     *
1540
     * @throws RestException 403 Forbidden
1541
     * @throws RestException 404 Error Bad or unknown value for constantname
1542
     */
1543
    public function getConf($constantname)
1544
    {
1545
    	global $conf;
1546
1547
    	if (!DolibarrApiAccess::$user->admin
1548
    		&& (empty($conf->global->API_LOGIN_ALLOWED_FOR_ADMIN_CHECK) || DolibarrApiAccess::$user->login != $conf->global->API_LOGIN_ALLOWED_FOR_ADMIN_CHECK)) {
1549
    		throw new RestException(403, 'Error API open to admin users only or to the login user defined with constant API_LOGIN_ALLOWED_FOR_ADMIN_CHECK');
1550
    	}
1551
1552
    	if (!preg_match('/^[a-zA-Z0-9_]+$/', $constantname) || !isset($conf->global->$constantname)) {
1553
    		throw new RestException(404, 'Error Bad or unknown value for constantname');
1554
    	}
1555
    	if (preg_match('/(_pass|_pw|password|secret|_key|key$)/i', $constantname)) {
1556
    		throw new RestException(403, 'Forbidden');
1557
    	}
1558
1559
    	return $conf->global->$constantname;
1560
    }
1561
1562
    /**
1563
     * Do a test of integrity for files and setup.
1564
     *
1565
     * @param string	$target			Can be 'local' or 'default' or Url of the signatures file to use for the test. Must be reachable by the tested Dolibarr.
1566
     * @return array					Result of file and setup integrity check
1567
     *
1568
     * @url     GET checkintegrity
1569
     *
1570
     * @throws RestException 404 Signature file not found
1571
     * @throws RestException 500 Technical error
1572
     * @throws RestException 503 Forbidden
1573
     */
1574
    public function getCheckIntegrity($target)
1575
    {
1576
    	global $langs, $conf;
1577
1578
    	if (!DolibarrApiAccess::$user->admin
1579
    		&& (empty($conf->global->API_LOGIN_ALLOWED_FOR_INTEGRITY_CHECK) || DolibarrApiAccess::$user->login != $conf->global->API_LOGIN_ALLOWED_FOR_INTEGRITY_CHECK))
1580
    	{
1581
    		throw new RestException(503, 'Error API open to admin users only or to the login user defined with constant API_LOGIN_ALLOWED_FOR_INTEGRITY_CHECK');
1582
    	}
1583
1584
    	require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1585
    	require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
1586
1587
    	$langs->load("admin");
1588
1589
    	$outexpectedchecksum = '';
1590
    	$outcurrentchecksum = '';
1591
1592
    	// Modified or missing files
1593
    	$file_list = array('missing' => array(), 'updated' => array());
1594
1595
    	// Local file to compare to
1596
    	$xmlshortfile = GETPOST('xmlshortfile') ?GETPOST('xmlshortfile') : '/install/filelist-'.DOL_VERSION.'.xml';
1597
    	$xmlfile = DOL_DOCUMENT_ROOT.$xmlshortfile;
1598
    	// Remote file to compare to
1599
    	$xmlremote = ($target == 'default' ? '' : $target);
1600
    	if (empty($xmlremote) && !empty($conf->global->MAIN_FILECHECK_URL)) $xmlremote = $conf->global->MAIN_FILECHECK_URL;
1601
    	$param = 'MAIN_FILECHECK_URL_'.DOL_VERSION;
1602
    	if (empty($xmlremote) && !empty($conf->global->$param)) $xmlremote = $conf->global->$param;
1603
    	if (empty($xmlremote)) $xmlremote = 'https://www.dolibarr.org/files/stable/signatures/filelist-'.DOL_VERSION.'.xml';
1604
1605
    	if ($target == 'local')
1606
    	{
1607
    		if (dol_is_file($xmlfile))
1608
    		{
1609
    			$xml = simplexml_load_file($xmlfile);
1610
    		} else {
1611
    			throw new RestException(500, $langs->trans('XmlNotFound').': '.$xmlfile);
1612
    		}
1613
    	} else {
1614
    		$xmlarray = getURLContent($xmlremote);
1615
1616
    		// Return array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...)
1617
    		if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != '404')
1618
    		{
1619
    			$xmlfile = $xmlarray['content'];
1620
    			//print "xmlfilestart".$xmlfile."endxmlfile";
1621
    			$xml = simplexml_load_string($xmlfile);
1622
    		} else {
1623
    			$errormsg = $langs->trans('XmlNotFound').': '.$xmlremote.' - '.$xmlarray['http_code'].' '.$xmlarray['curl_error_no'].' '.$xmlarray['curl_error_msg'];
1624
    			throw new RestException(500, $errormsg);
1625
    		}
1626
    	}
1627
1628
1629
1630
    	if ($xml)
1631
    	{
1632
    		$checksumconcat = array();
1633
    		$file_list = array();
1634
    		$out = '';
1635
1636
    		// Forced constants
1637
    		if (is_object($xml->dolibarr_constants[0]))
1638
    		{
1639
    			$out .= load_fiche_titre($langs->trans("ForcedConstants"));
1640
1641
    			$out .= '<div class="div-table-responsive-no-min">';
1642
    			$out .= '<table class="noborder">';
1643
    			$out .= '<tr class="liste_titre">';
1644
    			$out .= '<td>#</td>';
1645
    			$out .= '<td>'.$langs->trans("Constant").'</td>';
1646
    			$out .= '<td class="center">'.$langs->trans("ExpectedValue").'</td>';
1647
    			$out .= '<td class="center">'.$langs->trans("Value").'</td>';
1648
    			$out .= '</tr>'."\n";
1649
1650
    			$i = 0;
1651
    			foreach ($xml->dolibarr_constants[0]->constant as $constant)    // $constant is a simpleXMLElement
1652
    			{
1653
    				$constname = $constant['name'];
1654
    				$constvalue = (string) $constant;
1655
    				$constvalue = (empty($constvalue) ? '0' : $constvalue);
1656
    				// Value found
1657
    				$value = '';
1658
    				if ($constname && $conf->global->$constname != '') $value = $conf->global->$constname;
1659
    				$valueforchecksum = (empty($value) ? '0' : $value);
1660
1661
    				$checksumconcat[] = $valueforchecksum;
1662
1663
    				$i++;
1664
    				$out .= '<tr class="oddeven">';
1665
    				$out .= '<td>'.$i.'</td>'."\n";
1666
    				$out .= '<td>'.$constname.'</td>'."\n";
1667
    				$out .= '<td class="center">'.$constvalue.'</td>'."\n";
1668
    				$out .= '<td class="center">'.$valueforchecksum.'</td>'."\n";
1669
    				$out .= "</tr>\n";
1670
    			}
1671
1672
    			if ($i == 0)
1673
    			{
1674
    				$out .= '<tr class="oddeven"><td colspan="4" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
1675
    			}
1676
    			$out .= '</table>';
1677
    			$out .= '</div>';
1678
1679
    			$out .= '<br>';
1680
    		}
1681
1682
    		// Scan htdocs
1683
    		if (is_object($xml->dolibarr_htdocs_dir[0]))
1684
    		{
1685
    			//var_dump($xml->dolibarr_htdocs_dir[0]['includecustom']);exit;
1686
    			$includecustom = (empty($xml->dolibarr_htdocs_dir[0]['includecustom']) ? 0 : $xml->dolibarr_htdocs_dir[0]['includecustom']);
1687
1688
    			// Defined qualified files (must be same than into generate_filelist_xml.php)
1689
    			$regextoinclude = '\.(php|php3|php4|php5|phtml|phps|phar|inc|css|scss|html|xml|js|json|tpl|jpg|jpeg|png|gif|ico|sql|lang|txt|yml|bak|md|mp3|mp4|wav|mkv|z|gz|zip|rar|tar|less|svg|eot|woff|woff2|ttf|manifest)$';
1690
    			$regextoexclude = '('.($includecustom ? '' : 'custom|').'documents|conf|install|public\/test|Shared\/PCLZip|nusoap\/lib\/Mail|php\/example|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
1691
    			$scanfiles = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude);
1692
1693
    			// Fill file_list with files in signature, new files, modified files
1694
    			$ret = getFilesUpdated($file_list, $xml->dolibarr_htdocs_dir[0], '', DOL_DOCUMENT_ROOT, $checksumconcat); // Fill array $file_list
1695
    			// Complete with list of new files
1696
    			foreach ($scanfiles as $keyfile => $valfile)
1697
    			{
1698
    				$tmprelativefilename = preg_replace('/^'.preg_quote(DOL_DOCUMENT_ROOT, '/').'/', '', $valfile['fullname']);
1699
    				if (!in_array($tmprelativefilename, $file_list['insignature']))
1700
    				{
1701
    					$md5newfile = @md5_file($valfile['fullname']); // Can fails if we don't have permission to open/read file
1702
    					$file_list['added'][] = array('filename'=>$tmprelativefilename, 'md5'=>$md5newfile);
1703
    				}
1704
    			}
1705
1706
    			// Files missings
1707
    			$out .= load_fiche_titre($langs->trans("FilesMissing"));
1708
1709
    			$out .= '<div class="div-table-responsive-no-min">';
1710
    			$out .= '<table class="noborder">';
1711
    			$out .= '<tr class="liste_titre">';
1712
    			$out .= '<td>#</td>';
1713
    			$out .= '<td>'.$langs->trans("Filename").'</td>';
1714
    			$out .= '<td class="center">'.$langs->trans("ExpectedChecksum").'</td>';
1715
    			$out .= '</tr>'."\n";
1716
    			$tmpfilelist = dol_sort_array($file_list['missing'], 'filename');
1717
    			if (is_array($tmpfilelist) && count($tmpfilelist))
1718
    			{
1719
    				$i = 0;
1720
    				foreach ($tmpfilelist as $file)
1721
    				{
1722
    					$i++;
1723
    					$out .= '<tr class="oddeven">';
1724
    					$out .= '<td>'.$i.'</td>'."\n";
1725
    					$out .= '<td>'.$file['filename'].'</td>'."\n";
1726
    					$out .= '<td class="center">'.$file['expectedmd5'].'</td>'."\n";
1727
    					$out .= "</tr>\n";
1728
    				}
1729
    			} else {
1730
    				$out .= '<tr class="oddeven"><td colspan="3" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
1731
    			}
1732
    			$out .= '</table>';
1733
    			$out .= '</div>';
1734
1735
    			$out .= '<br>';
1736
1737
    			// Files modified
1738
    			$out .= load_fiche_titre($langs->trans("FilesModified"));
1739
1740
    			$totalsize = 0;
1741
    			$out .= '<div class="div-table-responsive-no-min">';
1742
    			$out .= '<table class="noborder">';
1743
    			$out .= '<tr class="liste_titre">';
1744
    			$out .= '<td>#</td>';
1745
    			$out .= '<td>'.$langs->trans("Filename").'</td>';
1746
    			$out .= '<td class="center">'.$langs->trans("ExpectedChecksum").'</td>';
1747
    			$out .= '<td class="center">'.$langs->trans("CurrentChecksum").'</td>';
1748
    			$out .= '<td class="right">'.$langs->trans("Size").'</td>';
1749
    			$out .= '<td class="right">'.$langs->trans("DateModification").'</td>';
1750
    			$out .= '</tr>'."\n";
1751
    			$tmpfilelist2 = dol_sort_array($file_list['updated'], 'filename');
1752
    			if (is_array($tmpfilelist2) && count($tmpfilelist2))
1753
    			{
1754
    				$i = 0;
1755
    				foreach ($tmpfilelist2 as $file)
1756
    				{
1757
    					$i++;
1758
    					$out .= '<tr class="oddeven">';
1759
    					$out .= '<td>'.$i.'</td>'."\n";
1760
    					$out .= '<td>'.$file['filename'].'</td>'."\n";
1761
    					$out .= '<td class="center">'.$file['expectedmd5'].'</td>'."\n";
1762
    					$out .= '<td class="center">'.$file['md5'].'</td>'."\n";
1763
    					$size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']);
1764
    					$totalsize += $size;
1765
    					$out .= '<td class="right">'.dol_print_size($size).'</td>'."\n";
1766
    					$out .= '<td class="right">'.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']), 'dayhour').'</td>'."\n";
1767
    					$out .= "</tr>\n";
1768
    				}
1769
    				$out .= '<tr class="liste_total">';
1770
    				$out .= '<td></td>'."\n";
1771
    				$out .= '<td>'.$langs->trans("Total").'</td>'."\n";
1772
    				$out .= '<td align="center"></td>'."\n";
1773
    				$out .= '<td align="center"></td>'."\n";
1774
    				$out .= '<td class="right">'.dol_print_size($totalsize).'</td>'."\n";
1775
    				$out .= '<td class="right"></td>'."\n";
1776
    				$out .= "</tr>\n";
1777
    			} else {
1778
    				$out .= '<tr class="oddeven"><td colspan="5" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
1779
    			}
1780
    			$out .= '</table>';
1781
    			$out .= '</div>';
1782
1783
    			$out .= '<br>';
1784
1785
    			// Files added
1786
    			$out .= load_fiche_titre($langs->trans("FilesAdded"));
1787
1788
    			$totalsize = 0;
1789
    			$out .= '<div class="div-table-responsive-no-min">';
1790
    			$out .= '<table class="noborder">';
1791
    			$out .= '<tr class="liste_titre">';
1792
    			$out .= '<td>#</td>';
1793
    			$out .= '<td>'.$langs->trans("Filename").'</td>';
1794
    			$out .= '<td class="center">'.$langs->trans("ExpectedChecksum").'</td>';
1795
    			$out .= '<td class="center">'.$langs->trans("CurrentChecksum").'</td>';
1796
    			$out .= '<td class="right">'.$langs->trans("Size").'</td>';
1797
    			$out .= '<td class="right">'.$langs->trans("DateModification").'</td>';
1798
    			$out .= '</tr>'."\n";
1799
    			$tmpfilelist3 = dol_sort_array($file_list['added'], 'filename');
1800
    			if (is_array($tmpfilelist3) && count($tmpfilelist3))
1801
    			{
1802
    				$i = 0;
1803
    				foreach ($tmpfilelist3 as $file)
1804
    				{
1805
    					$i++;
1806
    					$out .= '<tr class="oddeven">';
1807
    					$out .= '<td>'.$i.'</td>'."\n";
1808
    					$out .= '<td>'.$file['filename'].'</td>'."\n";
1809
    					$out .= '<td class="center">'.$file['expectedmd5'].'</td>'."\n";
1810
    					$out .= '<td class="center">'.$file['md5'].'</td>'."\n";
1811
    					$size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']);
1812
    					$totalsize += $size;
1813
    					$out .= '<td class="right">'.dol_print_size($size).'</td>'."\n";
1814
    					$out .= '<td class="right">'.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']), 'dayhour').'</td>'."\n";
1815
    					$out .= "</tr>\n";
1816
    				}
1817
    				$out .= '<tr class="liste_total">';
1818
    				$out .= '<td></td>'."\n";
1819
    				$out .= '<td>'.$langs->trans("Total").'</td>'."\n";
1820
    				$out .= '<td align="center"></td>'."\n";
1821
    				$out .= '<td align="center"></td>'."\n";
1822
    				$out .= '<td class="right">'.dol_print_size($totalsize).'</td>'."\n";
1823
    				$out .= '<td class="right"></td>'."\n";
1824
    				$out .= "</tr>\n";
1825
    			} else {
1826
    				$out .= '<tr class="oddeven"><td colspan="5" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
1827
    			}
1828
    			$out .= '</table>';
1829
    			$out .= '</div>';
1830
1831
1832
    			// Show warning
1833
    			if (empty($tmpfilelist) && empty($tmpfilelist2) && empty($tmpfilelist3))
1834
    			{
1835
    				//setEventMessages($langs->trans("FileIntegrityIsStrictlyConformedWithReference"), null, 'mesgs');
1836
    			} else {
1837
    				//setEventMessages($langs->trans("FileIntegritySomeFilesWereRemovedOrModified"), null, 'warnings');
1838
    			}
1839
    		} else {
1840
    			throw new RestException(500, 'Error: Failed to found dolibarr_htdocs_dir into XML file '.$xmlfile);
1841
    		}
1842
1843
1844
    		// Scan scripts
1845
1846
1847
    		asort($checksumconcat); // Sort list of checksum
1848
    		//var_dump($checksumconcat);
1849
    		$checksumget = md5(join(',', $checksumconcat));
1850
    		$checksumtoget = trim((string) $xml->dolibarr_htdocs_dir_checksum);
1851
1852
    		$outexpectedchecksum = ($checksumtoget ? $checksumtoget : $langs->trans("Unknown"));
1853
    		if ($checksumget == $checksumtoget)
1854
    		{
1855
    			if (count($file_list['added']))
1856
    			{
1857
    				$resultcode = 'warning';
1858
    				$resultcomment = 'FileIntegrityIsOkButFilesWereAdded';
1859
    				//$outcurrentchecksum =  $checksumget.' - <span class="'.$resultcode.'">'.$langs->trans("FileIntegrityIsOkButFilesWereAdded").'</span>';
1860
    				$outcurrentchecksum = $checksumget;
1861
    			} else {
1862
    				$resultcode = 'ok';
1863
    				$resultcomment = 'Success';
1864
    				//$outcurrentchecksum = '<span class="'.$resultcode.'">'.$checksumget.'</span>';
1865
    				$outcurrentchecksum = $checksumget;
1866
    			}
1867
    		} else {
1868
    			$resultcode = 'error';
1869
    			$resultcomment = 'Error';
1870
    			//$outcurrentchecksum = '<span class="'.$resultcode.'">'.$checksumget.'</span>';
1871
    			$outcurrentchecksum = $checksumget;
1872
    		}
1873
    	} else {
1874
    		throw new RestException(404, 'No signature file known');
1875
    	}
1876
1877
    	return array('resultcode'=>$resultcode, 'resultcomment'=>$resultcomment, 'expectedchecksum'=> $outexpectedchecksum, 'currentchecksum'=> $outcurrentchecksum, 'out'=>$out);
1878
    }
1879
}
1880