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

Setup::_fetchCstate()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 2
dl 0
loc 12
rs 10
c 0
b 0
f 0
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