dolibarr 21.0.0-beta
api_setup.class.php
1<?php
2/* Copyright (C) 2016 Xebax Christy <xebax@wanadoo.fr>
3 * Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2017 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2017 Neil Orley <neil.orley@oeris.fr>
6 * Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
7 * Copyright (C) 2018-2022 Thibault FOUCART <support@ptibogxiv.net>
8 * Copyright (C) 2024 Jon Bendtsen <jon.bendtsen.github@jonb.dk>
9 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
10 *
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
26use Luracast\Restler\RestException;
27
28require_once DOL_DOCUMENT_ROOT.'/main.inc.php';
29require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php';
30require_once DOL_DOCUMENT_ROOT.'/core/class/cstate.class.php';
31require_once DOL_DOCUMENT_ROOT.'/core/class/cregion.class.php';
32require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php';
33require_once DOL_DOCUMENT_ROOT.'/hrm/class/establishment.class.php';
34
41class Setup extends DolibarrApi
42{
46 private $translations = null;
47
51 public function __construct()
52 {
53 global $db;
54 $this->db = $db;
55 }
56
75 public function getListOfActionTriggers($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $elementtype = '', $lang = '', $sqlfilters = '')
76 {
77 $list = array();
78
79 if ($elementtype == 'thirdparty') {
80 $elementtype = 'societe';
81 }
82 if ($elementtype == 'contact') {
83 $elementtype = 'socpeople';
84 }
85
86 $sql = "SELECT t.rowid as id, t.elementtype, t.code, t.contexts, t.label, t.description, t.rang";
87 $sql .= " FROM ".MAIN_DB_PREFIX."c_action_trigger as t";
88 if (!empty($elementtype)) {
89 $sql .= " WHERE t.elementtype = '".$this->db->escape($elementtype)."'";
90 }
91 // Add sql filters
92 if ($sqlfilters) {
93 $errormessage = '';
94 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
95 if ($errormessage) {
96 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
97 }
98 }
99
100 $sql .= $this->db->order($sortfield, $sortorder);
101
102 if ($limit) {
103 if ($page < 0) {
104 $page = 0;
105 }
106 $offset = $limit * $page;
107
108 $sql .= $this->db->plimit($limit, $offset);
109 }
110
111 $result = $this->db->query($sql);
112 if ($result) {
113 $num = $this->db->num_rows($result);
114 $min = min($num, ($limit <= 0 ? $num : $limit));
115 for ($i = 0; $i < $min; $i++) {
116 $type = $this->db->fetch_object($result);
117 $this->translateLabel($type, $lang, 'Notify_', array('other'));
118 $list[] = $type;
119 }
120 } else {
121 throw new RestException(503, 'Error when retrieving list of action triggers : '.$this->db->lasterror());
122 }
123
124 return $list;
125 }
126
145 public function getOrderingMethods($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
146 {
147 $list = array();
148
149 if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) {
150 throw new RestException(403);
151 }
152
153 $sql = "SELECT rowid, code, libelle as label, module";
154 $sql .= " FROM ".MAIN_DB_PREFIX."c_input_method as t";
155 $sql .= " WHERE t.active = ".((int) $active);
156 // Add sql filters
157 if ($sqlfilters) {
158 $errormessage = '';
159 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
160 if ($errormessage) {
161 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
162 }
163 }
164
165
166 $sql .= $this->db->order($sortfield, $sortorder);
167
168 if ($limit) {
169 if ($page < 0) {
170 $page = 0;
171 }
172 $offset = $limit * $page;
173
174 $sql .= $this->db->plimit($limit, $offset);
175 }
176
177 $result = $this->db->query($sql);
178
179 if ($result) {
180 $num = $this->db->num_rows($result);
181 $min = min($num, ($limit <= 0 ? $num : $limit));
182 for ($i = 0; $i < $min; $i++) {
183 $list[] = $this->db->fetch_object($result);
184 }
185 } else {
186 throw new RestException(503, $this->db->lasterror());
187 }
188
189 return $list;
190 }
191
209 public function getOrderingOrigins($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
210 {
211 $list = array();
212
213 if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) {
214 throw new RestException(403);
215 }
216
217 $sql = "SELECT rowid, code, label, module";
218 $sql .= " FROM ".MAIN_DB_PREFIX."c_input_reason as t";
219 $sql .= " WHERE t.active = ".((int) $active);
220 // Add sql filters
221 if ($sqlfilters) {
222 $errormessage = '';
223 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
224 if ($errormessage) {
225 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
226 }
227 }
228
229
230 $sql .= $this->db->order($sortfield, $sortorder);
231
232 if ($limit) {
233 if ($page < 0) {
234 $page = 0;
235 }
236 $offset = $limit * $page;
237
238 $sql .= $this->db->plimit($limit, $offset);
239 }
240
241 $result = $this->db->query($sql);
242
243 if ($result) {
244 $num = $this->db->num_rows($result);
245 $min = min($num, ($limit <= 0 ? $num : $limit));
246 for ($i = 0; $i < $min; $i++) {
247 $list[] = $this->db->fetch_object($result);
248 }
249 } else {
250 throw new RestException(503, $this->db->lasterror());
251 }
252
253 return $list;
254 }
255
274 public function getPaymentTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
275 {
276 $list = array();
277
278 if (!DolibarrApiAccess::$user->hasRight('propal', 'lire') && !DolibarrApiAccess::$user->hasRight('commande', 'lire') && !DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
279 throw new RestException(403);
280 }
281
282 $sql = "SELECT id, code, type, libelle as label, module";
283 $sql .= " FROM ".MAIN_DB_PREFIX."c_paiement as t";
284 $sql .= " WHERE t.entity IN (".getEntity('c_paiement').")";
285 $sql .= " AND t.active = ".((int) $active);
286 // Add sql filters
287 if ($sqlfilters) {
288 $errormessage = '';
289 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
290 if ($errormessage) {
291 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
292 }
293 }
294
295
296 $sql .= $this->db->order($sortfield, $sortorder);
297
298 if ($limit) {
299 if ($page < 0) {
300 $page = 0;
301 }
302 $offset = $limit * $page;
303
304 $sql .= $this->db->plimit($limit, $offset);
305 }
306
307 $result = $this->db->query($sql);
308
309 if ($result) {
310 $num = $this->db->num_rows($result);
311 $min = min($num, ($limit <= 0 ? $num : $limit));
312 for ($i = 0; $i < $min; $i++) {
313 $list[] = $this->db->fetch_object($result);
314 }
315 } else {
316 throw new RestException(503, $this->db->lasterror());
317 }
318
319 return $list;
320 }
340 public function getListOfRegions($sortfield = "code_region", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $filter = '', $sqlfilters = '')
341 {
342 $list = array();
343
344 // Note: The filter is not applied in the SQL request because it must
345 // be applied to the translated names, not to the names in database.
346 $sql = "SELECT t.rowid FROM ".MAIN_DB_PREFIX."c_regions as t";
347 $sql .= " WHERE 1 = 1";
348 if ($country) {
349 $sql .= " AND t.fk_pays = ".((int) $country);
350 }
351 // Add sql filters
352 if ($sqlfilters) {
353 $errormessage = '';
354 if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
355 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
356 }
357 $regexstring = '\‍(([^:\'\‍(\‍)]+:[^:\'\‍(\‍)]+:[^\‍(\‍)]+)\‍)';
358 $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
359 }
360
361 $sql .= $this->db->order($sortfield, $sortorder);
362
363 if ($limit) {
364 if ($page < 0) {
365 $page = 0;
366 }
367 $offset = $limit * $page;
368
369 $sql .= $this->db->plimit($limit, $offset);
370 }
371
372 $result = $this->db->query($sql);
373
374 if ($result) {
375 $num = $this->db->num_rows($result);
376 $min = min($num, ($limit <= 0 ? $num : $limit));
377 for ($i = 0; $i < $min; $i++) {
378 $obj = $this->db->fetch_object($result);
379 $region = new Cregion($this->db);
380 if ($region->fetch($obj->rowid) > 0) {
381 if (empty($filter) || stripos($region->name, $filter) !== false) {
382 $list[] = $this->_cleanObjectDatas($region);
383 }
384 }
385 }
386 } else {
387 throw new RestException(503, 'Error when retrieving list of regions');
388 }
389
390 return $list;
391 }
392
404 public function getRegionByID($id)
405 {
406 return $this->_fetchCregion($id, '');
407 }
408
420 public function getRegionByCode($code)
421 {
422 return $this->_fetchCregion(0, $code);
423 }
424
447 public function getListOfStates($sortfield = "code_departement", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $filter = '', $sqlfilters = '')
448 {
449 $list = array();
450
451 // Note: The filter is not applied in the SQL request because it must
452 // be applied to the translated names, not to the names in database.
453 $sql = "SELECT t.rowid FROM ".MAIN_DB_PREFIX."c_departements as t";
454 if ($country) {
455 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_regions as d ON t.fk_region = d.code_region";
456 }
457 $sql .= " WHERE 1 = 1";
458 if ($country) {
459 $sql .= " AND d.fk_pays = ".((int) $country);
460 }
461 // Add sql filters
462 if ($sqlfilters) {
463 $errormessage = '';
464 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
465 if ($errormessage) {
466 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
467 }
468 }
469
470 $sql .= $this->db->order($sortfield, $sortorder);
471
472 if ($limit) {
473 if ($page < 0) {
474 $page = 0;
475 }
476 $offset = $limit * $page;
477
478 $sql .= $this->db->plimit($limit, $offset);
479 }
480
481 $result = $this->db->query($sql);
482
483 if ($result) {
484 $num = $this->db->num_rows($result);
485 $min = min($num, ($limit <= 0 ? $num : $limit));
486 for ($i = 0; $i < $min; $i++) {
487 $obj = $this->db->fetch_object($result);
488 $state = new Cstate($this->db);
489 if ($state->fetch($obj->rowid) > 0) {
490 if (empty($filter) || stripos($state->label, $filter) !== false) {
491 $list[] = $this->_cleanObjectDatas($state);
492 }
493 }
494 }
495 } else {
496 throw new RestException(503, 'Error when retrieving list of states');
497 }
498
499 return $list;
500 }
501
513 public function getStateByID($id)
514 {
515 return $this->_fetchCstate($id, '');
516 }
517
529 public function getStateByCode($code)
530 {
531 return $this->_fetchCstate(0, $code);
532 }
533
556 public function getListOfCountries($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $lang = '', $sqlfilters = '')
557 {
558 $list = array();
559
560 // Note: The filter is not applied in the SQL request because it must
561 // be applied to the translated names, not to the names in database.
562 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_country as t";
563 $sql .= " WHERE 1 = 1";
564 // Add sql filters
565 if ($sqlfilters) {
566 $errormessage = '';
567 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
568 if ($errormessage) {
569 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
570 }
571 }
572
573 $sql .= $this->db->order($sortfield, $sortorder);
574
575 if ($limit) {
576 if ($page < 0) {
577 $page = 0;
578 }
579 $offset = $limit * $page;
580
581 $sql .= $this->db->plimit($limit, $offset);
582 }
583
584 $result = $this->db->query($sql);
585
586 if ($result) {
587 $num = $this->db->num_rows($result);
588 $min = min($num, ($limit <= 0 ? $num : $limit));
589 for ($i = 0; $i < $min; $i++) {
590 $obj = $this->db->fetch_object($result);
591 $country = new Ccountry($this->db);
592 if ($country->fetch($obj->rowid) > 0) {
593 // Translate the name of the country if needed
594 // and then apply the filter if there is one.
595 $this->translateLabel($country, $lang, 'Country');
596
597 if (empty($filter) || stripos($country->label, $filter) !== false) {
598 $list[] = $this->_cleanObjectDatas($country);
599 }
600 }
601 }
602 } else {
603 throw new RestException(503, 'Error when retrieving list of countries');
604 }
605
606 return $list;
607 }
608
621 public function getCountryByID($id, $lang = '')
622 {
623 return $this->_fetchCcountry($id, '', '', $lang);
624 }
625
638 public function getCountryByCode($code, $lang = '')
639 {
640 return $this->_fetchCcountry(0, $code, '', $lang);
641 }
642
655 public function getCountryByISO($iso, $lang = '')
656 {
657 return $this->_fetchCcountry(0, '', $iso, $lang);
658 }
659
669 private function _fetchCregion($id, $code = '')
670 {
671 $region = new Cregion($this->db);
672
673 $result = $region->fetch($id, $code);
674 if ($result < 0) {
675 throw new RestException(503, 'Error when retrieving region : '.$region->error);
676 } elseif ($result == 0) {
677 throw new RestException(404, 'Region not found');
678 }
679
680 return $this->_cleanObjectDatas($region);
681 }
682
692 private function _fetchCstate($id, $code = '')
693 {
694 $state = new Cstate($this->db);
695
696 $result = $state->fetch($id, $code);
697 if ($result < 0) {
698 throw new RestException(503, 'Error when retrieving state : '.$state->error);
699 } elseif ($result == 0) {
700 throw new RestException(404, 'State not found');
701 }
702
703 return $this->_cleanObjectDatas($state);
704 }
705
717 private function _fetchCcountry($id, $code = '', $iso = '', $lang = '')
718 {
719 $country = new Ccountry($this->db);
720
721 $result = $country->fetch($id, $code, $iso);
722
723 if ($result < 0) {
724 throw new RestException(503, 'Error when retrieving country : '.$country->error);
725 } elseif ($result == 0) {
726 throw new RestException(404, 'Country not found');
727 }
728
729 $this->translateLabel($country, $lang, 'Country');
730
731 return $this->_cleanObjectDatas($country);
732 }
733
752 public function getAvailability($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
753 {
754 $list = array();
755
756 if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) {
757 throw new RestException(403);
758 }
759
760 $sql = "SELECT rowid, code, label";
761 $sql .= " FROM ".MAIN_DB_PREFIX."c_availability as t";
762 $sql .= " WHERE t.active = ".((int) $active);
763 // Add sql filters
764 if ($sqlfilters) {
765 $errormessage = '';
766 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
767 if ($errormessage) {
768 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
769 }
770 }
771
772
773 $sql .= $this->db->order($sortfield, $sortorder);
774
775 if ($limit) {
776 if ($page < 0) {
777 $page = 0;
778 }
779 $offset = $limit * $page;
780
781 $sql .= $this->db->plimit($limit, $offset);
782 }
783
784 $result = $this->db->query($sql);
785
786 if ($result) {
787 $num = $this->db->num_rows($result);
788 $min = min($num, ($limit <= 0 ? $num : $limit));
789 for ($i = 0; $i < $min; $i++) {
790 $list[] = $this->db->fetch_object($result);
791 }
792 } else {
793 throw new RestException(503, $this->db->lasterror());
794 }
795
796 return $list;
797 }
798
799 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
806 protected function _cleanObjectDatas($object)
807 {
808 // phpcs:enable
809 $object = parent::_cleanObjectDatas($object);
810
811 unset($object->error);
812 unset($object->errors);
813
814 return $object;
815 }
816
826 private function translateLabel($object, $lang, $prefix = 'Country', $dict = array('dict'))
827 {
828 if (!empty($lang)) {
829 // Load the translations if this is a new language.
830 if ($this->translations == null || $this->translations->getDefaultLang() !== $lang) {
831 global $conf;
832 $this->translations = new Translate('', $conf);
833 $this->translations->setDefaultLang($lang);
834 $this->translations->loadLangs($dict);
835 }
836 if ($object->code) {
837 $key = $prefix.$object->code;
838
839 $translation = $this->translations->trans($key);
840 if ($translation != $key) {
841 $object->label = html_entity_decode($translation);
842 }
843 }
844 }
845 }
846
865 public function getListOfEventTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $active = 1, $sqlfilters = '')
866 {
867 $list = array();
868
869 $sql = "SELECT id, code, type, libelle as label, module";
870 $sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm as t";
871 $sql .= " WHERE t.active = ".((int) $active);
872 if ($type) {
873 $sql .= " AND t.type LIKE '%".$this->db->escape($type)."%'";
874 }
875 if ($module) {
876 $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
877 }
878 // Add sql filters
879 if ($sqlfilters) {
880 $errormessage = '';
881 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
882 if ($errormessage) {
883 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
884 }
885 }
886
887
888 $sql .= $this->db->order($sortfield, $sortorder);
889
890 if ($limit) {
891 if ($page < 0) {
892 $page = 0;
893 }
894 $offset = $limit * $page;
895
896 $sql .= $this->db->plimit($limit, $offset);
897 }
898
899 $result = $this->db->query($sql);
900
901 if ($result) {
902 $num = $this->db->num_rows($result);
903 $min = min($num, ($limit <= 0 ? $num : $limit));
904 for ($i = 0; $i < $min; $i++) {
905 $list[] = $this->db->fetch_object($result);
906 }
907 } else {
908 throw new RestException(503, 'Error when retrieving list of events types : '.$this->db->lasterror());
909 }
910
911 return $list;
912 }
913
914
932 public function getListOfExpenseReportsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $module = '', $active = 1, $sqlfilters = '')
933 {
934 $list = array();
935
936 $sql = "SELECT id, code, label, accountancy_code, active, module, position";
937 $sql .= " FROM ".MAIN_DB_PREFIX."c_type_fees as t";
938 $sql .= " WHERE t.active = ".((int) $active);
939 if ($module) {
940 $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
941 }
942 // Add sql filters
943 if ($sqlfilters) {
944 $errormessage = '';
945 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
946 if ($errormessage) {
947 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
948 }
949 }
950
951
952 $sql .= $this->db->order($sortfield, $sortorder);
953
954 if ($limit) {
955 if ($page < 0) {
956 $page = 0;
957 }
958 $offset = $limit * $page;
959
960 $sql .= $this->db->plimit($limit, $offset);
961 }
962
963 $result = $this->db->query($sql);
964
965 if ($result) {
966 $num = $this->db->num_rows($result);
967 $min = min($num, ($limit <= 0 ? $num : $limit));
968 for ($i = 0; $i < $min; $i++) {
969 $list[] = $this->db->fetch_object($result);
970 }
971 } else {
972 throw new RestException(503, 'Error when retrieving list of expense report types : '.$this->db->lasterror());
973 }
974
975 return $list;
976 }
977
978
998 public function getListOfContactTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $active = 1, $lang = '', $sqlfilters = '')
999 {
1000 $list = array();
1001
1002 $sql = "SELECT rowid, code, element as type, libelle as label, source, module, position";
1003 $sql .= " FROM ".MAIN_DB_PREFIX."c_type_contact as t";
1004 $sql .= " WHERE t.active = ".((int) $active);
1005 if ($type) {
1006 $sql .= " AND type LIKE '%".$this->db->escape($type)."%'";
1007 }
1008 if ($module) {
1009 $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
1010 }
1011 // Add sql filters
1012 if ($sqlfilters) {
1013 $errormessage = '';
1014 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1015 if ($errormessage) {
1016 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1017 }
1018 }
1019
1020
1021 $sql .= $this->db->order($sortfield, $sortorder);
1022
1023 if ($limit) {
1024 if ($page < 0) {
1025 $page = 0;
1026 }
1027 $offset = $limit * $page;
1028
1029 $sql .= $this->db->plimit($limit, $offset);
1030 }
1031
1032 $result = $this->db->query($sql);
1033
1034 if ($result) {
1035 $num = $this->db->num_rows($result);
1036 $min = min($num, ($limit <= 0 ? $num : $limit));
1037 for ($i = 0; $i < $min; $i++) {
1038 $contact_type = $this->db->fetch_object($result);
1039 $this->translateLabel($contact_type, $lang, 'TypeContact_'.$contact_type->type.'_'.$contact_type->source.'_', array("eventorganization", "resource", "projects", "contracts", "bills", "orders", "agenda", "propal", "stocks", "supplier_proposal", "interventions", "sendings", "ticket"));
1040 $list[] = $contact_type;
1041 }
1042 } else {
1043 throw new RestException(503, 'Error when retrieving list of contacts types : '.$this->db->lasterror());
1044 }
1045
1046 return $list;
1047 }
1048
1067 public function getListOfCivilities($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $module = '', $active = 1, $lang = '', $sqlfilters = '')
1068 {
1069 $list = array();
1070
1071 $sql = "SELECT rowid, code, label, module";
1072 $sql .= " FROM ".MAIN_DB_PREFIX."c_civility as t";
1073 $sql .= " WHERE t.active = ".((int) $active);
1074 if ($module) {
1075 $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
1076 }
1077 // Add sql filters
1078 if ($sqlfilters) {
1079 $errormessage = '';
1080 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1081 if ($errormessage) {
1082 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1083 }
1084 }
1085
1086
1087 $sql .= $this->db->order($sortfield, $sortorder);
1088
1089 if ($limit) {
1090 if ($page < 0) {
1091 $page = 0;
1092 }
1093 $offset = $limit * $page;
1094
1095 $sql .= $this->db->plimit($limit, $offset);
1096 }
1097
1098 $result = $this->db->query($sql);
1099
1100 if ($result) {
1101 $num = $this->db->num_rows($result);
1102 $min = min($num, ($limit <= 0 ? $num : $limit));
1103 for ($i = 0; $i < $min; $i++) {
1104 $civility = $this->db->fetch_object($result);
1105 $this->translateLabel($civility, $lang, 'Civility', array('dict'));
1106 $list[] = $civility;
1107 }
1108 } else {
1109 throw new RestException(503, 'Error when retrieving list of civility : '.$this->db->lasterror());
1110 }
1111
1112 return $list;
1113 }
1114
1132 public function getListOfCurrencies($multicurrency = 0, $sortfield = "code_iso", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1133 {
1134 $list = array();
1135 $sql = "SELECT t.code_iso, t.label, t.unicode";
1136 if (!empty($multicurrency)) {
1137 $sql .= " , cr.date_sync, cr.rate ";
1138 }
1139 $sql .= " FROM ".MAIN_DB_PREFIX."c_currencies as t";
1140 if (!empty($multicurrency)) {
1141 $sql .= " JOIN ".MAIN_DB_PREFIX."multicurrency as m ON m.code=t.code_iso";
1142 $sql .= " JOIN ".MAIN_DB_PREFIX."multicurrency_rate as cr ON (m.rowid = cr.fk_multicurrency)";
1143 }
1144 $sql .= " WHERE t.active = ".((int) $active);
1145 if (!empty($multicurrency)) {
1146 $sql .= " AND m.entity IN (".getEntity('multicurrency').")";
1147 if (!empty($multicurrency) && $multicurrency != 2) {
1148 $sql .= " AND cr.date_sync = (SELECT MAX(cr2.date_sync) FROM ".MAIN_DB_PREFIX."multicurrency_rate AS cr2 WHERE cr2.fk_multicurrency = m.rowid)";
1149 }
1150 }
1151
1152 // Add sql filters
1153 if ($sqlfilters) {
1154 $errormessage = '';
1155 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1156 if ($errormessage) {
1157 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1158 }
1159 }
1160
1161
1162 $sql .= $this->db->order($sortfield, $sortorder);
1163
1164 if ($limit) {
1165 if ($page < 0) {
1166 $page = 0;
1167 }
1168 $offset = $limit * $page;
1169
1170 $sql .= $this->db->plimit($limit, $offset);
1171 }
1172
1173 $result = $this->db->query($sql);
1174
1175 if ($result) {
1176 $num = $this->db->num_rows($result);
1177 $min = min($num, ($limit <= 0 ? $num : $limit));
1178 for ($i = 0; $i < $min; $i++) {
1179 $list[] = $this->db->fetch_object($result);
1180 }
1181 } else {
1182 throw new RestException(503, 'Error when retrieving list of currency : '.$this->db->lasterror());
1183 }
1184
1185 return $list;
1186 }
1187
1202 public function getListOfExtrafields($sortfield = "t.pos", $sortorder = 'ASC', $elementtype = '', $sqlfilters = '')
1203 {
1204 $list = array();
1205
1206 if (!DolibarrApiAccess::$user->admin
1207 && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_EXTRAFIELDS') || DolibarrApiAccess::$user->login != getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_EXTRAFIELDS'))) {
1208 throw new RestException(403, 'Error API open to admin users only or to the users with logins defined into constant API_LOGINS_ALLOWED_FOR_GET_EXTRAFIELDS');
1209 }
1210
1211 if ($elementtype == 'thirdparty') {
1212 $elementtype = 'societe';
1213 }
1214 if ($elementtype == 'contact') {
1215 $elementtype = 'socpeople';
1216 }
1217
1218 $sql = "SELECT t.rowid as id, t.name, t.entity, t.elementtype, t.label, t.type, t.size, t.fieldcomputed, t.fielddefault,";
1219 $sql .= " t.fieldunique, t.fieldrequired, t.perms, t.enabled, t.pos, t.alwayseditable, t.param, t.list, t.printable,";
1220 $sql .= " t.totalizable, t.langs, t.help, t.css, t.cssview, t.csslist, t.fk_user_author, t.fk_user_modif, t.datec, t.tms";
1221 $sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
1222 $sql .= " WHERE t.entity IN (".getEntity('extrafields').")";
1223 if (!empty($elementtype)) {
1224 $sql .= " AND t.elementtype = '".$this->db->escape($elementtype)."'";
1225 }
1226 // Add sql filters
1227 if ($sqlfilters) {
1228 $errormessage = '';
1229 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1230 if ($errormessage) {
1231 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1232 }
1233 }
1234
1235 $sql .= $this->db->order($sortfield, $sortorder);
1236
1237 $resql = $this->db->query($sql);
1238 if ($resql) {
1239 if ($this->db->num_rows($resql)) {
1240 while ($tab = $this->db->fetch_object($resql)) {
1241 // New usage
1242 $list[$tab->elementtype][$tab->name]['id'] = $tab->id;
1243 $list[$tab->elementtype][$tab->name]['type'] = $tab->type;
1244 $list[$tab->elementtype][$tab->name]['label'] = $tab->label;
1245 $list[$tab->elementtype][$tab->name]['size'] = $tab->size;
1246 $list[$tab->elementtype][$tab->name]['elementtype'] = $tab->elementtype;
1247 $list[$tab->elementtype][$tab->name]['default'] = $tab->fielddefault;
1248 $list[$tab->elementtype][$tab->name]['computed'] = $tab->fieldcomputed;
1249 $list[$tab->elementtype][$tab->name]['unique'] = $tab->fieldunique;
1250 $list[$tab->elementtype][$tab->name]['required'] = $tab->fieldrequired;
1251 $list[$tab->elementtype][$tab->name]['param'] = ($tab->param ? jsonOrUnserialize($tab->param) : ''); // This may be a string encoded with serialise() or json_encode()
1252 $list[$tab->elementtype][$tab->name]['pos'] = $tab->pos;
1253 $list[$tab->elementtype][$tab->name]['alwayseditable'] = $tab->alwayseditable;
1254 $list[$tab->elementtype][$tab->name]['perms'] = $tab->perms;
1255 $list[$tab->elementtype][$tab->name]['list'] = $tab->list;
1256 $list[$tab->elementtype][$tab->name]['printable'] = $tab->printable;
1257 $list[$tab->elementtype][$tab->name]['totalizable'] = $tab->totalizable;
1258 $list[$tab->elementtype][$tab->name]['langs'] = $tab->langs;
1259 $list[$tab->elementtype][$tab->name]['help'] = $tab->help;
1260 $list[$tab->elementtype][$tab->name]['css'] = $tab->css;
1261 $list[$tab->elementtype][$tab->name]['cssview'] = $tab->cssview;
1262 $list[$tab->elementtype][$tab->name]['csslist'] = $tab->csslist;
1263 $list[$tab->elementtype][$tab->name]['fk_user_author'] = $tab->fk_user_author;
1264 $list[$tab->elementtype][$tab->name]['fk_user_modif'] = $tab->fk_user_modif;
1265 $list[$tab->elementtype][$tab->name]['datec'] = $tab->datec;
1266 $list[$tab->elementtype][$tab->name]['tms'] = $tab->tms;
1267 }
1268 }
1269 } else {
1270 throw new RestException(503, 'Error when retrieving list of extra fields : '.$this->db->lasterror());
1271 }
1272
1273 return $list;
1274 }
1275
1286 public function deleteExtrafieldsFromNames($attrname, $elementtype)
1287 {
1288 if (!DolibarrApiAccess::$user->admin) {
1289 throw new RestException(403, 'Only an admin user can delete an extrafield by attrname and elementtype');
1290 }
1291
1292 $extrafields = new ExtraFields($this->db);
1293
1294 $result = $extrafields->fetch_name_optionals_label($elementtype, false, $attrname);
1295 if (!$result) {
1296 throw new RestException(404, 'Extrafield not found from attrname and elementtype');
1297 }
1298
1299 if (!$extrafields->delete($attrname, $elementtype)) {
1300 throw new RestException(500, 'Error when delete extrafield : '.$extrafields->error);
1301 }
1302
1303 return array(
1304 'success' => array(
1305 'code' => 200,
1306 'message' => 'Extrafield deleted from attrname and elementtype'
1307 )
1308 );
1309 }
1310
1311
1312
1324 public function getExtrafields($attrname, $elementtype)
1325 {
1326 $answer = array();
1327
1328 if (!DolibarrApiAccess::$user->admin) {
1329 throw new RestException(403, 'Only an admin user can get list of extrafields');
1330 }
1331
1332 if ($elementtype == 'thirdparty') {
1333 $elementtype = 'societe';
1334 }
1335 if ($elementtype == 'contact') {
1336 $elementtype = 'socpeople';
1337 }
1338
1339 $sql = "SELECT t.rowid as id, t.name, t.entity, t.elementtype, t.label, t.type, t.size, t.fieldcomputed, t.fielddefault,";
1340 $sql .= " t.fieldunique, t.fieldrequired, t.perms, t.enabled, t.pos, t.alwayseditable, t.param, t.list, t.printable,";
1341 $sql .= " t.totalizable, t.langs, t.help, t.css, t.cssview, t.csslist, t.fk_user_author, t.fk_user_modif, t.datec, t.tms";
1342 $sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
1343 $sql .= " WHERE t.entity IN (".getEntity('extrafields').")";
1344 $sql .= " AND t.elementtype = '".$this->db->escape($elementtype)."'";
1345 $sql .= " AND t.name = '".$this->db->escape($attrname)."'";
1346
1347 $resql = $this->db->query($sql);
1348 if ($resql) {
1349 if ($this->db->num_rows($resql)) {
1350 while ($tab = $this->db->fetch_object($resql)) {
1351 // New usage
1352 $answer[$tab->elementtype][$tab->name]['id'] = $tab->id;
1353 $answer[$tab->elementtype][$tab->name]['type'] = $tab->type;
1354 $answer[$tab->elementtype][$tab->name]['label'] = $tab->label;
1355 $answer[$tab->elementtype][$tab->name]['size'] = $tab->size;
1356 $answer[$tab->elementtype][$tab->name]['elementtype'] = $tab->elementtype;
1357 $answer[$tab->elementtype][$tab->name]['default'] = $tab->fielddefault;
1358 $answer[$tab->elementtype][$tab->name]['computed'] = $tab->fieldcomputed;
1359 $answer[$tab->elementtype][$tab->name]['unique'] = $tab->fieldunique;
1360 $answer[$tab->elementtype][$tab->name]['required'] = $tab->fieldrequired;
1361 $answer[$tab->elementtype][$tab->name]['param'] = ($tab->param ? jsonOrUnserialize($tab->param) : ''); // This may be a string encoded with serialise() or json_encode()
1362 $answer[$tab->elementtype][$tab->name]['pos'] = $tab->pos;
1363 $answer[$tab->elementtype][$tab->name]['alwayseditable'] = $tab->alwayseditable;
1364 $answer[$tab->elementtype][$tab->name]['perms'] = $tab->perms;
1365 $answer[$tab->elementtype][$tab->name]['list'] = $tab->list;
1366 $answer[$tab->elementtype][$tab->name]['printable'] = $tab->printable;
1367 $answer[$tab->elementtype][$tab->name]['totalizable'] = $tab->totalizable;
1368 $answer[$tab->elementtype][$tab->name]['langs'] = $tab->langs;
1369 $answer[$tab->elementtype][$tab->name]['help'] = $tab->help;
1370 $answer[$tab->elementtype][$tab->name]['css'] = $tab->css;
1371 $answer[$tab->elementtype][$tab->name]['cssview'] = $tab->cssview;
1372 $answer[$tab->elementtype][$tab->name]['csslist'] = $tab->csslist;
1373 $answer[$tab->elementtype][$tab->name]['fk_user_author'] = $tab->fk_user_author;
1374 $answer[$tab->elementtype][$tab->name]['fk_user_modif'] = $tab->fk_user_modif;
1375 $answer[$tab->elementtype][$tab->name]['datec'] = $tab->datec;
1376 $answer[$tab->elementtype][$tab->name]['tms'] = $tab->tms;
1377 }
1378 } else {
1379 throw new RestException(404, 'Extrafield not found from attrname and elementtype');
1380 }
1381 } else {
1382 throw new RestException(503, 'Error when retrieving list of extra fields : '.$this->db->lasterror());
1383 }
1384
1385 return $answer;
1386 }
1387
1401 public function postExtrafields($attrname, $elementtype, $request_data = null)
1402 {
1403 if (!DolibarrApiAccess::$user->admin) {
1404 throw new RestException(403, 'Only an admin user can create an extrafield');
1405 }
1406
1407 $extrafields = new ExtraFields($this->db);
1408
1409 $result = $extrafields->fetch_name_optionals_label($elementtype, false, $attrname);
1410 if ($result) {
1411 throw new RestException(409, 'Duplicate extrafield already found from attrname and elementtype');
1412 }
1413
1414 // Check mandatory fields is not working despise being a modified copy from api_thirdparties.class.php
1415 // $result = $this->_validateExtrafields($request_data, $extrafields);
1416
1417 foreach ($request_data as $field => $value) {
1418 $extrafields->$field = $this->_checkValForAPI($field, $value, $extrafields);
1419 }
1420
1421 $entity = DolibarrApiAccess::$user->entity;
1422 if (empty($entity)) {
1423 $entity = 1;
1424 }
1425
1426 // built in validation
1427 $enabled = 1; // hardcoded because it seems to always be 1 in every row in the database
1428
1429 if ($request_data['label']) {
1430 $label = $request_data['label'];
1431 } else {
1432 throw new RestException(400, "label field absent in json at root level");
1433 }
1434
1435 $alwayseditable = $request_data['alwayseditable'];
1436 $default_value = $request_data['default_value'];
1437 $totalizable = $request_data['totalizable'];
1438 $printable = $request_data['printable'];
1439 $required = $request_data['required'];
1440 $langfile = $request_data['langfile'];
1441 $computed = $request_data['computed'];
1442 $unique = $request_data['unique'];
1443 $param = $request_data['param'];
1444 $perms = $request_data['perms'];
1445 $size = $request_data['size'];
1446 $type = $request_data['type'];
1447 $list = $request_data['list'];
1448 $help = $request_data['help'];
1449 $pos = $request_data['pos'];
1450 $moreparams = array();
1451
1452 if (0 > $extrafields->addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $default_value, $param, $alwayseditable, $perms, $list, $help, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams)) {
1453 throw new RestException(500, 'Error creating extrafield', array_merge(array($extrafields->errno), $extrafields->errors));
1454 }
1455
1456 $sql = "SELECT t.rowid as id";
1457 $sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
1458 $sql .= " WHERE elementtype = '".$this->db->escape($elementtype)."'";
1459 $sql .= " AND name = '".$this->db->escape($attrname)."'";
1460
1461 $resql = $this->db->query($sql);
1462 if ($resql) {
1463 if ($this->db->num_rows($resql)) {
1464 $tab = $this->db->fetch_object($resql);
1465 $id = (int) $tab->id;
1466 } else {
1467 $id = (int) -1;
1468 }
1469 } else {
1470 $id = (int) -2;
1471 }
1472
1473 return $id;
1474 }
1475
1490 public function updateExtrafields($attrname, $elementtype, $request_data = null)
1491 {
1492 if (!DolibarrApiAccess::$user->admin) {
1493 throw new RestException(403, 'Only an admin user can create an extrafield');
1494 }
1495
1496 $extrafields = new ExtraFields($this->db);
1497
1498 $result = $extrafields->fetch_name_optionals_label($elementtype, false, $attrname);
1499 if (!$result) {
1500 throw new RestException(404, 'Extrafield not found from attrname and elementtype');
1501 }
1502
1503 foreach ($request_data as $field => $value) {
1504 $extrafields->$field = $this->_checkValForAPI($field, $value, $extrafields);
1505 }
1506
1507 $entity = DolibarrApiAccess::$user->entity;
1508 if (empty($entity)) {
1509 $entity = 1;
1510 }
1511
1512 // built in validation
1513 $enabled = 1; // hardcoded because it seems to always be 1 in every row in the database
1514 if ($request_data['label']) {
1515 $label = $request_data['label'];
1516 } else {
1517 throw new RestException(400, "label field absent in json at root level");
1518 }
1519
1520 $alwayseditable = $request_data['alwayseditable'];
1521 $default_value = $request_data['default_value'];
1522 $totalizable = $request_data['totalizable'];
1523 $printable = $request_data['printable'];
1524 $required = $request_data['required'];
1525 $langfile = $request_data['langfile'];
1526 $computed = $request_data['computed'];
1527 $unique = $request_data['unique'];
1528 $param = $request_data['param'];
1529 $perms = $request_data['perms'];
1530 $size = $request_data['size'];
1531 $type = $request_data['type'];
1532 $list = $request_data['list'];
1533 $help = $request_data['help'];
1534 $pos = $request_data['pos'];
1535 $moreparams = array();
1536
1537 dol_syslog(get_class($this).'::updateExtraField', LOG_DEBUG);
1538 if (0 > $extrafields->updateExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $default_value, $param, $alwayseditable, $perms, $list, $help, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams)) {
1539 throw new RestException(500, 'Error updating extrafield', array_merge(array($extrafields->errno), $extrafields->errors));
1540 }
1541
1542 $sql = "SELECT t.rowid as id";
1543 $sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
1544 $sql .= " WHERE elementtype = '".$this->db->escape($elementtype)."'";
1545 $sql .= " AND name = '".$this->db->escape($attrname)."'";
1546
1547 $resql = $this->db->query($sql);
1548 if ($resql) {
1549 if ($this->db->num_rows($resql)) {
1550 $tab = $this->db->fetch_object($resql);
1551 $id = (int) $tab->id;
1552 } else {
1553 $id = (int) -1;
1554 }
1555 } else {
1556 $id = (int) -2;
1557 }
1558
1559 return $id;
1560 }
1561
1580 public function getListOfTowns($sortfield = "zip,town", $sortorder = 'ASC', $limit = 100, $page = 0, $zipcode = '', $town = '', $active = 1, $sqlfilters = '')
1581 {
1582 $list = array();
1583
1584 $sql = "SELECT rowid AS id, zip, town, fk_county, fk_pays AS fk_country";
1585 $sql .= " FROM ".MAIN_DB_PREFIX."c_ziptown as t";
1586 $sql .= " WHERE t.active = ".((int) $active);
1587 if ($zipcode) {
1588 $sql .= " AND t.zip LIKE '%".$this->db->escape($zipcode)."%'";
1589 }
1590 if ($town) {
1591 $sql .= " AND t.town LIKE '%".$this->db->escape($town)."%'";
1592 }
1593 // Add sql filters
1594 if ($sqlfilters) {
1595 $errormessage = '';
1596 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1597 if ($errormessage) {
1598 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1599 }
1600 }
1601
1602
1603 $sql .= $this->db->order($sortfield, $sortorder);
1604
1605 if ($limit) {
1606 if ($page < 0) {
1607 $page = 0;
1608 }
1609 $offset = $limit * $page;
1610
1611 $sql .= $this->db->plimit($limit, $offset);
1612 }
1613
1614 $result = $this->db->query($sql);
1615
1616 if ($result) {
1617 $num = $this->db->num_rows($result);
1618 $min = min($num, ($limit <= 0 ? $num : $limit));
1619 for ($i = 0; $i < $min; $i++) {
1620 $list[] = $this->db->fetch_object($result);
1621 }
1622 } else {
1623 throw new RestException(503, 'Error when retrieving list of towns : '.$this->db->lasterror());
1624 }
1625
1626 return $list;
1627 }
1628
1647 public function getPaymentTerms($sortfield = "sortorder", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1648 {
1649 $list = array();
1650
1651 if (!DolibarrApiAccess::$user->hasRight('propal', 'lire') && !DolibarrApiAccess::$user->hasRight('commande', 'lire') && !DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
1652 throw new RestException(403);
1653 }
1654
1655 $sql = "SELECT rowid as id, code, sortorder, libelle as label, libelle_facture as descr, type_cdr, nbjour, decalage, module";
1656 $sql .= " FROM ".MAIN_DB_PREFIX."c_payment_term as t";
1657 $sql .= " WHERE t.entity IN (".getEntity('c_payment_term').")";
1658 $sql .= " AND t.active = ".((int) $active);
1659 // Add sql filters
1660 if ($sqlfilters) {
1661 $errormessage = '';
1662 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1663 if ($errormessage) {
1664 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1665 }
1666 }
1667
1668
1669 $sql .= $this->db->order($sortfield, $sortorder);
1670
1671 if ($limit) {
1672 if ($page < 0) {
1673 $page = 0;
1674 }
1675 $offset = $limit * $page;
1676
1677 $sql .= $this->db->plimit($limit, $offset);
1678 }
1679
1680 $result = $this->db->query($sql);
1681
1682 if ($result) {
1683 $num = $this->db->num_rows($result);
1684 $min = min($num, ($limit <= 0 ? $num : $limit));
1685 for ($i = 0; $i < $min; $i++) {
1686 $list[] = $this->db->fetch_object($result);
1687 }
1688 } else {
1689 throw new RestException(503, $this->db->lasterror());
1690 }
1691
1692 return $list;
1693 }
1694
1711 public function getShippingModes($limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
1712 {
1713 $list = array();
1714
1715 $sql = "SELECT rowid as id, code, libelle as label, description, tracking, module";
1716 $sql .= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as t";
1717 $sql .= " WHERE t.entity IN (".getEntity('c_shipment_mode').")";
1718 $sql .= " AND t.active = ".((int) $active);
1719 // Add sql filters
1720 if ($sqlfilters) {
1721 $errormessage = '';
1722 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1723 if ($errormessage) {
1724 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1725 }
1726 }
1727
1728
1729 //$sql.= $this->db->order($sortfield, $sortorder);
1730
1731 if ($limit) {
1732 if ($page < 0) {
1733 $page = 0;
1734 }
1735 $offset = $limit * $page;
1736
1737 $sql .= $this->db->plimit($limit, $offset);
1738 }
1739
1740 $result = $this->db->query($sql);
1741
1742 if ($result) {
1743 $num = $this->db->num_rows($result);
1744 $min = min($num, ($limit <= 0 ? $num : $limit));
1745 for ($i = 0; $i < $min; $i++) {
1746 $method = $this->db->fetch_object($result);
1747 $this->translateLabel($method, $lang, '', array('dict'));
1748 $list[] = $method;
1749 }
1750 } else {
1751 throw new RestException(503, $this->db->lasterror());
1752 }
1753
1754 return $list;
1755 }
1756
1773 public function getListOfMeasuringUnits($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1774 {
1775 $list = array();
1776
1777 $sql = "SELECT t.rowid, t.code, t.label,t.short_label, t.active, t.scale, t.unit_type";
1778 $sql .= " FROM ".MAIN_DB_PREFIX."c_units as t";
1779 $sql .= " WHERE t.active = ".((int) $active);
1780 // Add sql filters
1781 if ($sqlfilters) {
1782 $errormessage = '';
1783 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1784 if ($errormessage) {
1785 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1786 }
1787 }
1788
1789
1790 $sql .= $this->db->order($sortfield, $sortorder);
1791
1792 if ($limit) {
1793 if ($page < 0) {
1794 $page = 0;
1795 }
1796 $offset = $limit * $page;
1797
1798 $sql .= $this->db->plimit($limit, $offset);
1799 }
1800
1801 $result = $this->db->query($sql);
1802
1803 if ($result) {
1804 $num = $this->db->num_rows($result);
1805 $min = min($num, ($limit <= 0 ? $num : $limit));
1806 for ($i = 0; $i < $min; $i++) {
1807 $list[] = $this->db->fetch_object($result);
1808 }
1809 } else {
1810 throw new RestException(503, 'Error when retrieving list of measuring units: '.$this->db->lasterror());
1811 }
1812
1813 return $list;
1814 }
1815
1833 public function getListOfLegalForm($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $active = 1, $sqlfilters = '')
1834 {
1835 $list = array();
1836
1837 $sql = "SELECT t.rowid, t.code, t.fk_pays, t.libelle, t.isvatexempted, t.active, t.module, t.position";
1838 $sql .= " FROM ".MAIN_DB_PREFIX."c_forme_juridique as t";
1839 $sql .= " WHERE t.active = ".((int) $active);
1840 if ($country) {
1841 $sql .= " AND t.fk_pays = ".((int) $country);
1842 }
1843 // Add sql filters
1844 if ($sqlfilters) {
1845 $errormessage = '';
1846 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1847 if ($errormessage) {
1848 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1849 }
1850 }
1851
1852
1853 $sql .= $this->db->order($sortfield, $sortorder);
1854
1855 if ($limit) {
1856 if ($page < 0) {
1857 $page = 0;
1858 }
1859 $offset = $limit * $page;
1860
1861 $sql .= $this->db->plimit($limit, $offset);
1862 }
1863
1864 $result = $this->db->query($sql);
1865
1866 if ($result) {
1867 $num = $this->db->num_rows($result);
1868 $min = min($num, ($limit <= 0 ? $num : $limit));
1869 for ($i = 0; $i < $min; $i++) {
1870 $list[] = $this->db->fetch_object($result);
1871 }
1872 } else {
1873 throw new RestException(503, 'Error when retrieving list of legal form: '.$this->db->lasterror());
1874 }
1875
1876 return $list;
1877 }
1878
1895 public function getListOfStaff($sortfield = "id", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1896 {
1897 $list = array();
1898
1899 $sql = "SELECT t.id, t.code, t.libelle, t.active, t.module";
1900 $sql .= " FROM ".MAIN_DB_PREFIX."c_effectif as t";
1901 $sql .= " WHERE t.active = ".((int) $active);
1902 // Add sql filters
1903 if ($sqlfilters) {
1904 $errormessage = '';
1905 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1906 if ($errormessage) {
1907 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1908 }
1909 }
1910
1911
1912 $sql .= $this->db->order($sortfield, $sortorder);
1913
1914 if ($limit) {
1915 if ($page < 0) {
1916 $page = 0;
1917 }
1918 $offset = $limit * $page;
1919
1920 $sql .= $this->db->plimit($limit, $offset);
1921 }
1922
1923 $result = $this->db->query($sql);
1924
1925 if ($result) {
1926 $num = $this->db->num_rows($result);
1927 $min = min($num, ($limit <= 0 ? $num : $limit));
1928 for ($i = 0; $i < $min; $i++) {
1929 $list[] = $this->db->fetch_object($result);
1930 }
1931 } else {
1932 throw new RestException(503, 'Error when retrieving list of staff: '.$this->db->lasterror());
1933 }
1934
1935 return $list;
1936 }
1937
1954 public function getListOfsocialNetworks($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1955 {
1956 global $conf;
1957
1958 if (!isModEnabled('socialnetworks')) {
1959 throw new RestException(400, 'API not available: this dictionary is not enabled by setup');
1960 }
1961
1962 $list = array();
1963 //TODO link with multicurrency module
1964 $sql = "SELECT t.rowid, t.entity, t.code, t.label, t.url, t.icon, t.active";
1965 $sql .= " FROM ".MAIN_DB_PREFIX."c_socialnetworks as t";
1966 $sql .= " WHERE t.entity IN (".getEntity('c_socialnetworks').")";
1967 $sql .= " AND t.active = ".((int) $active);
1968 // Add sql filters
1969 if ($sqlfilters) {
1970 $errormessage = '';
1971 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1972 if ($errormessage) {
1973 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1974 }
1975 }
1976
1977
1978 $sql .= $this->db->order($sortfield, $sortorder);
1979
1980 if ($limit) {
1981 if ($page < 0) {
1982 $page = 0;
1983 }
1984 $offset = $limit * $page;
1985
1986 $sql .= $this->db->plimit($limit, $offset);
1987 }
1988
1989 $result = $this->db->query($sql);
1990
1991 if ($result) {
1992 $num = $this->db->num_rows($result);
1993 $min = min($num, ($limit <= 0 ? $num : $limit));
1994 for ($i = 0; $i < $min; $i++) {
1995 $list[] = $this->db->fetch_object($result);
1996 }
1997 } else {
1998 throw new RestException(503, 'Error when retrieving list of social networks: '.$this->db->lasterror());
1999 }
2000
2001 return $list;
2002 }
2003
2021 public function getTicketsCategories($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
2022 {
2023 $list = array();
2024
2025 $sql = "SELECT rowid, code, pos, label, use_default, description";
2026 $sql .= " FROM ".MAIN_DB_PREFIX."c_ticket_category as t";
2027 $sql .= " WHERE t.entity IN (".getEntity('c_ticket_category').")";
2028 $sql .= " AND t.active = ".((int) $active);
2029 // Add sql filters
2030 if ($sqlfilters) {
2031 $errormessage = '';
2032 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
2033 if ($errormessage) {
2034 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
2035 }
2036 }
2037
2038
2039 $sql .= $this->db->order($sortfield, $sortorder);
2040
2041 if ($limit) {
2042 if ($page < 0) {
2043 $page = 0;
2044 }
2045 $offset = $limit * $page;
2046
2047 $sql .= $this->db->plimit($limit, $offset);
2048 }
2049
2050 $result = $this->db->query($sql);
2051
2052 if ($result) {
2053 $num = $this->db->num_rows($result);
2054 $min = min($num, ($limit <= 0 ? $num : $limit));
2055 for ($i = 0; $i < $min; $i++) {
2056 $category = $this->db->fetch_object($result);
2057 $this->translateLabel($category, $lang, 'TicketCategoryShort', array('ticket'));
2058 $list[] = $category;
2059 }
2060 } else {
2061 throw new RestException(503, 'Error when retrieving list of ticket categories : '.$this->db->lasterror());
2062 }
2063
2064 return $list;
2065 }
2066
2084 public function getTicketsSeverities($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
2085 {
2086 $list = array();
2087
2088 $sql = "SELECT rowid, code, pos, label, use_default, color, description";
2089 $sql .= " FROM ".MAIN_DB_PREFIX."c_ticket_severity as t";
2090 $sql .= " WHERE t.entity IN (".getEntity('c_ticket_severity').")";
2091 $sql .= " AND t.active = ".((int) $active);
2092 // Add sql filters
2093 if ($sqlfilters) {
2094 $errormessage = '';
2095 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
2096 if ($errormessage) {
2097 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
2098 }
2099 }
2100
2101
2102 $sql .= $this->db->order($sortfield, $sortorder);
2103
2104 if ($limit) {
2105 if ($page < 0) {
2106 $page = 0;
2107 }
2108 $offset = $limit * $page;
2109
2110 $sql .= $this->db->plimit($limit, $offset);
2111 }
2112
2113 $result = $this->db->query($sql);
2114
2115 if ($result) {
2116 $num = $this->db->num_rows($result);
2117 $min = min($num, ($limit <= 0 ? $num : $limit));
2118 for ($i = 0; $i < $min; $i++) {
2119 $severity = $this->db->fetch_object($result);
2120 $this->translateLabel($severity, $lang, 'TicketSeverityShort', array('ticket'));
2121 $list[] = $severity;
2122 }
2123 } else {
2124 throw new RestException(503, 'Error when retrieving list of ticket severities : '.$this->db->lasterror());
2125 }
2126
2127 return $list;
2128 }
2129
2147 public function getTicketsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
2148 {
2149 $list = array();
2150
2151 $sql = "SELECT rowid, code, pos, label, use_default, description";
2152 $sql .= " FROM ".MAIN_DB_PREFIX."c_ticket_type as t";
2153 $sql .= " WHERE t.entity IN (".getEntity('c_ticket_type').")";
2154 $sql .= " AND t.active = ".((int) $active);
2155
2156 // Add sql filters
2157 if ($sqlfilters) {
2158 $errormessage = '';
2159 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
2160 if ($errormessage) {
2161 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
2162 }
2163 }
2164
2165
2166 $sql .= $this->db->order($sortfield, $sortorder);
2167
2168 if ($limit) {
2169 if ($page < 0) {
2170 $page = 0;
2171 }
2172 $offset = $limit * $page;
2173
2174 $sql .= $this->db->plimit($limit, $offset);
2175 }
2176
2177 $result = $this->db->query($sql);
2178
2179 if ($result) {
2180 $num = $this->db->num_rows($result);
2181 $min = min($num, ($limit <= 0 ? $num : $limit));
2182 for ($i = 0; $i < $min; $i++) {
2183 $type = $this->db->fetch_object($result);
2184 $this->translateLabel($type, $lang, 'TicketTypeShort', array('ticket'));
2185 $list[] = $type;
2186 }
2187 } else {
2188 throw new RestException(503, 'Error when retrieving list of ticket types : '.$this->db->lasterror());
2189 }
2190
2191 return $list;
2192 }
2193
2210 public function getListOfIncoterms($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
2211 {
2212 $list = array();
2213
2214 $sql = "SELECT rowid, code, active";
2215 $sql .= " FROM ".MAIN_DB_PREFIX."c_incoterms as t";
2216 $sql .= " WHERE 1=1";
2217
2218 // Add sql filters
2219 if ($sqlfilters) {
2220 $errormessage = '';
2221 if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
2222 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
2223 }
2224 $regexstring = '\‍(([^:\'\‍(\‍)]+:[^:\'\‍(\‍)]+:[^\‍(\‍)]+)\‍)';
2225 $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
2226 }
2227
2228
2229 $sql .= $this->db->order($sortfield, $sortorder);
2230
2231 if ($limit) {
2232 if ($page < 0) {
2233 $page = 0;
2234 }
2235 $offset = $limit * $page;
2236
2237 $sql .= $this->db->plimit($limit, $offset);
2238 }
2239
2240 $result = $this->db->query($sql);
2241
2242 if ($result) {
2243 $num = $this->db->num_rows($result);
2244 $min = min($num, ($limit <= 0 ? $num : $limit));
2245 for ($i = 0; $i < $min; $i++) {
2246 $type = $this->db->fetch_object($result);
2247 $list[] = $type;
2248 }
2249 } else {
2250 throw new RestException(503, 'Error when retrieving list of incoterm types : '.$this->db->lasterror());
2251 }
2252
2253 return $list;
2254 }
2255
2265 public function getCompany()
2266 {
2267 global $conf, $mysoc;
2268
2269 if (!DolibarrApiAccess::$user->admin
2270 && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_COMPANY') || DolibarrApiAccess::$user->login != getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_COMPANY'))) {
2271 throw new RestException(403, 'Error API open to admin users only or to the users with logins defined into constant API_LOGINS_ALLOWED_FOR_GET_COMPANY');
2272 }
2273
2274 unset($mysoc->pays);
2275 unset($mysoc->note);
2276 unset($mysoc->nom);
2277
2278 unset($mysoc->lines);
2279
2280 unset($mysoc->effectif);
2281 unset($mysoc->effectif_id);
2282 unset($mysoc->forme_juridique_code);
2283 unset($mysoc->forme_juridique);
2284 unset($mysoc->mode_reglement_supplier_id);
2285 unset($mysoc->cond_reglement_supplier_id);
2286 unset($mysoc->transport_mode_supplier_id);
2287 unset($mysoc->fk_prospectlevel);
2288
2289 unset($mysoc->total_ht);
2290 unset($mysoc->total_tva);
2291 unset($mysoc->total_localtax1);
2292 unset($mysoc->total_localtax2);
2293 unset($mysoc->total_ttc);
2294
2295 unset($mysoc->lastname);
2296 unset($mysoc->firstname);
2297 unset($mysoc->civility_id);
2298
2299 unset($mysoc->client);
2300 unset($mysoc->prospect);
2301 unset($mysoc->fournisseur);
2302 unset($mysoc->contact_id);
2303
2304 unset($mysoc->fk_incoterms);
2305 unset($mysoc->label_incoterms);
2306 unset($mysoc->location_incoterms);
2307
2308 return $this->_cleanObjectDatas($mysoc);
2309 }
2310
2320 public function getEstablishments()
2321 {
2322 $list = array();
2323
2324 $limit = 0;
2325
2326 $sql = "SELECT e.rowid, e.rowid as ref, e.label, e.address, e.zip, e.town, e.status";
2327 $sql .= " FROM ".MAIN_DB_PREFIX."establishment as e";
2328 $sql .= " WHERE e.entity IN (".getEntity('establishment').')';
2329 // if ($type) $sql .= " AND t.type LIKE '%".$this->db->escape($type)."%'";
2330 // if ($module) $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
2331 // Add sql filters
2332
2333 $result = $this->db->query($sql);
2334
2335 if ($result) {
2336 $num = $this->db->num_rows($result);
2337 $min = min($num, ($limit <= 0 ? $num : $limit));
2338 for ($i = 0; $i < $min; $i++) {
2339 $list[] = $this->db->fetch_object($result);
2340 }
2341 } else {
2342 throw new RestException(503, 'Error when retrieving list of establishments : '.$this->db->lasterror());
2343 }
2344
2345 return $list;
2346 }
2347
2359 public function getEtablishmentByID($id)
2360 {
2361 $establishment = new Establishment($this->db);
2362
2363 $result = $establishment->fetch($id);
2364 if ($result < 0) {
2365 throw new RestException(503, 'Error when retrieving establishment : '.$establishment->error);
2366 } elseif ($result == 0) {
2367 throw new RestException(404, 'Establishment not found');
2368 }
2369
2370 return $this->_cleanObjectDatas($establishment);
2371 }
2372
2386 public function getConf($constantname)
2387 {
2388 global $conf;
2389
2390 if (!DolibarrApiAccess::$user->admin
2391 && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_CONST_READ') || DolibarrApiAccess::$user->login != getDolGlobalString('API_LOGINS_ALLOWED_FOR_CONST_READ'))) {
2392 throw new RestException(403, 'Error API open to admin users only or to the users with logins defined into constant API_LOGINS_ALLOWED_FOR_CONST_READ');
2393 }
2394
2395 if (!preg_match('/^[a-zA-Z0-9_]+$/', $constantname) || !isset($conf->global->$constantname)) {
2396 throw new RestException(400, 'Error Bad or unknown value for constantname');
2397 }
2398 if (isASecretKey($constantname)) {
2399 throw new RestException(403, 'Forbidden. This parameter can not be read with APIs');
2400 }
2401
2402 return getDolGlobalString($constantname);
2403 }
2404
2417 public function getCheckIntegrity($target)
2418 {
2419 global $langs, $conf;
2420
2421 if (!DolibarrApiAccess::$user->admin
2422 && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_INTEGRITY_CHECK') || DolibarrApiAccess::$user->login != getDolGlobalString('API_LOGINS_ALLOWED_FOR_INTEGRITY_CHECK'))) {
2423 throw new RestException(403, 'Error API open to admin users only or to the users with logins defined into constant API_LOGINS_ALLOWED_FOR_INTEGRITY_CHECK');
2424 }
2425
2426 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
2427 require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
2428
2429 $langs->load("admin");
2430
2431 $outexpectedchecksum = '';
2432 $outcurrentchecksum = '';
2433
2434 // Modified or missing files
2435 $file_list = array('missing' => array(), 'updated' => array());
2436
2437 // Local file to compare to
2438 $xmlshortfile = dol_sanitizeFileName('filelist-'.DOL_VERSION.getDolGlobalString('MAIN_FILECHECK_LOCAL_SUFFIX').'.xml'.getDolGlobalString('MAIN_FILECHECK_LOCAL_EXT'));
2439
2440 $xmlfile = DOL_DOCUMENT_ROOT.'/install/'.$xmlshortfile;
2441 if (!preg_match('/\.zip$/i', $xmlfile) && dol_is_file($xmlfile.'.zip')) {
2442 $xmlfile .= '.zip';
2443 }
2444
2445 // Remote file to compare to
2446 $xmlremote = (($target == 'default' || $target == 'local') ? '' : $target);
2447 if (empty($xmlremote) && getDolGlobalString('MAIN_FILECHECK_URL')) {
2448 $xmlremote = getDolGlobalString('MAIN_FILECHECK_URL');
2449 }
2450 $param = 'MAIN_FILECHECK_URL_'.DOL_VERSION;
2451 if (empty($xmlremote) && getDolGlobalString($param)) {
2452 $xmlremote = getDolGlobalString($param);
2453 }
2454 if (empty($xmlremote)) {
2455 $xmlremote = 'https://www.dolibarr.org/files/stable/signatures/filelist-'.DOL_VERSION.'.xml';
2456 }
2457 if ($xmlremote && !preg_match('/^https?:\/\//i', $xmlremote)) {
2458 $langs->load("errors");
2459 throw new RestException(500, $langs->trans("ErrorURLMustStartWithHttp", $xmlremote));
2460 }
2461 if ($xmlremote && !preg_match('/\.xml$/', $xmlremote)) {
2462 $langs->load("errors");
2463 throw new RestException(500, $langs->trans("ErrorURLMustEndWith", $xmlremote, '.xml'));
2464 }
2465
2466 if (LIBXML_VERSION < 20900) {
2467 // Avoid load of external entities (security problem).
2468 // Required only if LIBXML_VERSION < 20900
2469 // @phan-suppress-next-line PhanDeprecatedFunctionInternal
2470 libxml_disable_entity_loader(true);
2471 }
2472
2473 if ($target == 'local') {
2474 if (dol_is_file($xmlfile)) {
2475 $xml = simplexml_load_file($xmlfile);
2476 } else {
2477 throw new RestException(500, $langs->trans('XmlNotFound').': /install/'.$xmlshortfile);
2478 }
2479 } else {
2480 $xmlarray = getURLContent($xmlremote, 'GET', '', 1, array(), array('http', 'https'), 0); // Accept http or https links on external remote server only. Same is used into filecheck.php.
2481
2482 // Return array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...)
2483 if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != '400' && $xmlarray['http_code'] != '404') {
2484 $xmlfile = $xmlarray['content'];
2485 //print "xmlfilestart".$xmlfile."endxmlfile";
2486 $xml = simplexml_load_string($xmlfile, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NONET);
2487 } else {
2488 $errormsg = $langs->trans('XmlNotFound').': '.$xmlremote.' - '.$xmlarray['http_code'].(($xmlarray['http_code'] == 400 && $xmlarray['content']) ? ' '.$xmlarray['content'] : '').' '.$xmlarray['curl_error_no'].' '.$xmlarray['curl_error_msg'];
2489 throw new RestException(500, $errormsg);
2490 }
2491 }
2492
2493 if ($xml) {
2494 $checksumconcat = array();
2495 $file_list = array();
2496 $out = '';
2497
2498 // Forced constants
2499 if (is_object($xml->dolibarr_constants[0])) {
2500 $out .= load_fiche_titre($langs->trans("ForcedConstants"));
2501
2502 $out .= '<div class="div-table-responsive-no-min">';
2503 $out .= '<table class="noborder">';
2504 $out .= '<tr class="liste_titre">';
2505 $out .= '<td>#</td>';
2506 $out .= '<td>'.$langs->trans("Constant").'</td>';
2507 $out .= '<td class="center">'.$langs->trans("ExpectedValue").'</td>';
2508 $out .= '<td class="center">'.$langs->trans("Value").'</td>';
2509 $out .= '</tr>'."\n";
2510
2511 $i = 0;
2512 foreach ($xml->dolibarr_constants[0]->constant as $constant) { // $constant is a simpleXMLElement
2513 $constname = $constant['name'];
2514 $constvalue = (string) $constant;
2515 $constvalue = (empty($constvalue) ? '0' : $constvalue);
2516 // Value found
2517 $value = '';
2518 if ($constname && getDolGlobalString($constname) != '') {
2519 $value = getDolGlobalString($constname);
2520 }
2521 $valueforchecksum = (empty($value) ? '0' : $value);
2522
2523 $checksumconcat[] = $valueforchecksum;
2524
2525 $i++;
2526 $out .= '<tr class="oddeven">';
2527 $out .= '<td>'.$i.'</td>'."\n";
2528 $out .= '<td>'.dol_escape_htmltag($constname).'</td>'."\n";
2529 $out .= '<td class="center">'.dol_escape_htmltag($constvalue).'</td>'."\n";
2530 $out .= '<td class="center">'.dol_escape_htmltag($valueforchecksum).'</td>'."\n";
2531 $out .= "</tr>\n";
2532 }
2533
2534 if ($i == 0) {
2535 $out .= '<tr class="oddeven"><td colspan="4" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
2536 }
2537 $out .= '</table>';
2538 $out .= '</div>';
2539
2540 $out .= '<br>';
2541 }
2542
2543 // Scan htdocs
2544 if (is_object($xml->dolibarr_htdocs_dir[0])) {
2545 $includecustom = (empty($xml->dolibarr_htdocs_dir[0]['includecustom']) ? 0 : $xml->dolibarr_htdocs_dir[0]['includecustom']);
2546
2547 // Define qualified files (must be same than into generate_filelist_xml.php and in api_setup.class.php)
2548 $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)$';
2549 $regextoexclude = '('.($includecustom ? '' : 'custom|').'documents|conf|install|dejavu-fonts-ttf-.*|public\/test|sabre\/sabre\/.*\/tests|Shared\/PCLZip|nusoap\/lib\/Mail|php\/example|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
2550 $scanfiles = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude);
2551
2552 // Fill file_list with files in signature, new files, modified files
2553 $ret = getFilesUpdated($file_list, $xml->dolibarr_htdocs_dir[0], '', DOL_DOCUMENT_ROOT, $checksumconcat); // Fill array $file_list
2554 '@phan-var-force array{insignature:string[],missing?:array<array{filename:string,expectedmd5:string,expectedsize:string}>,updated:array<array{filename:string,expectedmd5:string,expectedsize:string,md5:string}>} $file_list';
2555 // Complete with list of new files
2556 foreach ($scanfiles as $keyfile => $valfile) {
2557 $tmprelativefilename = preg_replace('/^'.preg_quote(DOL_DOCUMENT_ROOT, '/').'/', '', $valfile['fullname']);
2558 if (!in_array($tmprelativefilename, $file_list['insignature'])) {
2559 $md5newfile = @md5_file($valfile['fullname']); // Can fails if we don't have permission to open/read file
2560 $file_list['added'][] = array('filename' => $tmprelativefilename, 'md5' => $md5newfile);
2561 }
2562 }
2563
2564 // Files missing
2565 $out .= load_fiche_titre($langs->trans("FilesMissing"));
2566
2567 $out .= '<div class="div-table-responsive-no-min">';
2568 $out .= '<table class="noborder">';
2569 $out .= '<tr class="liste_titre">';
2570 $out .= '<td>#</td>';
2571 $out .= '<td>'.$langs->trans("Filename").'</td>';
2572 $out .= '<td class="center">'.$langs->trans("ExpectedChecksum").'</td>';
2573 $out .= '</tr>'."\n";
2574 $tmpfilelist = dol_sort_array($file_list['missing'], 'filename');
2575 if (is_array($tmpfilelist) && count($tmpfilelist)) {
2576 $i = 0;
2577 foreach ($tmpfilelist as $file) {
2578 $i++;
2579 $out .= '<tr class="oddeven">';
2580 $out .= '<td>'.$i.'</td>'."\n";
2581 $out .= '<td>'.dol_escape_htmltag($file['filename']).'</td>'."\n";
2582 $out .= '<td class="center">'.(array_key_exists('expectedmd5', $file) ? $file['expectedmd5'] : '').'</td>'."\n";
2583 $out .= "</tr>\n";
2584 }
2585 } else {
2586 $out .= '<tr class="oddeven"><td colspan="3" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
2587 }
2588 $out .= '</table>';
2589 $out .= '</div>';
2590
2591 $out .= '<br>';
2592
2593 // Files modified
2594 $out .= load_fiche_titre($langs->trans("FilesModified"));
2595
2596 $totalsize = 0;
2597 $out .= '<div class="div-table-responsive-no-min">';
2598 $out .= '<table class="noborder">';
2599 $out .= '<tr class="liste_titre">';
2600 $out .= '<td>#</td>';
2601 $out .= '<td>'.$langs->trans("Filename").'</td>';
2602 $out .= '<td class="center">'.$langs->trans("ExpectedChecksum").'</td>';
2603 $out .= '<td class="center">'.$langs->trans("CurrentChecksum").'</td>';
2604 $out .= '<td class="right">'.$langs->trans("Size").'</td>';
2605 $out .= '<td class="right">'.$langs->trans("DateModification").'</td>';
2606 $out .= '</tr>'."\n";
2607 $tmpfilelist2 = dol_sort_array($file_list['updated'], 'filename');
2608 if (is_array($tmpfilelist2) && count($tmpfilelist2)) {
2609 $i = 0;
2610 foreach ($tmpfilelist2 as $file) {
2611 $i++;
2612 $out .= '<tr class="oddeven">';
2613 $out .= '<td>'.$i.'</td>'."\n";
2614 $out .= '<td>'.dol_escape_htmltag($file['filename']).'</td>'."\n";
2615 $out .= '<td class="center">'.$file['expectedmd5'].'</td>'."\n";
2616 $out .= '<td class="center">'.$file['md5'].'</td>'."\n";
2617 $size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']);
2618 $totalsize += $size;
2619 $out .= '<td class="right">'.dol_print_size($size).'</td>'."\n";
2620 $out .= '<td class="right">'.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']), 'dayhour').'</td>'."\n";
2621 $out .= "</tr>\n";
2622 }
2623 $out .= '<tr class="liste_total">';
2624 $out .= '<td></td>'."\n";
2625 $out .= '<td>'.$langs->trans("Total").'</td>'."\n";
2626 $out .= '<td align="center"></td>'."\n";
2627 $out .= '<td align="center"></td>'."\n";
2628 $out .= '<td class="right">'.dol_print_size($totalsize).'</td>'."\n";
2629 $out .= '<td class="right"></td>'."\n";
2630 $out .= "</tr>\n";
2631 } else {
2632 $out .= '<tr class="oddeven"><td colspan="5" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
2633 }
2634 $out .= '</table>';
2635 $out .= '</div>';
2636
2637 $out .= '<br>';
2638
2639 // Files added
2640 $out .= load_fiche_titre($langs->trans("FilesAdded"));
2641
2642 $totalsize = 0;
2643 $out .= '<div class="div-table-responsive-no-min">';
2644 $out .= '<table class="noborder">';
2645 $out .= '<tr class="liste_titre">';
2646 $out .= '<td>#</td>';
2647 $out .= '<td>'.$langs->trans("Filename").'</td>';
2648 $out .= '<td class="center">'.$langs->trans("ExpectedChecksum").'</td>';
2649 $out .= '<td class="center">'.$langs->trans("CurrentChecksum").'</td>';
2650 $out .= '<td class="right">'.$langs->trans("Size").'</td>';
2651 $out .= '<td class="right">'.$langs->trans("DateModification").'</td>';
2652 $out .= '</tr>'."\n";
2653 $tmpfilelist3 = dol_sort_array($file_list['added'], 'filename');
2654 if (is_array($tmpfilelist3) && count($tmpfilelist3)) {
2655 $i = 0;
2656 foreach ($tmpfilelist3 as $file) {
2657 $i++;
2658 $out .= '<tr class="oddeven">';
2659 $out .= '<td>'.$i.'</td>'."\n";
2660 $out .= '<td>'.dol_escape_htmltag($file['filename']).'</td>'."\n";
2661 $out .= '<td class="center">'.$file['expectedmd5'].'</td>'."\n"; // @phan-suppress-current-line PhanTypeInvalidDimOffset,PhanTypeSuspiciousStringExpression
2662 $out .= '<td class="center">'.$file['md5'].'</td>'."\n";
2663 $size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']);
2664 $totalsize += $size;
2665 $out .= '<td class="right">'.dol_print_size($size).'</td>'."\n";
2666 $out .= '<td class="right">'.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']), 'dayhour').'</td>'."\n";
2667 $out .= "</tr>\n";
2668 }
2669 $out .= '<tr class="liste_total">';
2670 $out .= '<td></td>'."\n";
2671 $out .= '<td>'.$langs->trans("Total").'</td>'."\n";
2672 $out .= '<td align="center"></td>'."\n";
2673 $out .= '<td align="center"></td>'."\n";
2674 $out .= '<td class="right">'.dol_print_size($totalsize).'</td>'."\n";
2675 $out .= '<td class="right"></td>'."\n";
2676 $out .= "</tr>\n";
2677 } else {
2678 $out .= '<tr class="oddeven"><td colspan="5" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
2679 }
2680 $out .= '</table>';
2681 $out .= '</div>';
2682
2683
2684 // Show warning
2685 if (empty($tmpfilelist) && empty($tmpfilelist2) && empty($tmpfilelist3)) {
2686 //setEventMessages($langs->trans("FileIntegrityIsStrictlyConformedWithReference"), null, 'mesgs');
2687 } else {
2688 //setEventMessages($langs->trans("FileIntegritySomeFilesWereRemovedOrModified"), null, 'warnings');
2689 }
2690 } else {
2691 throw new RestException(500, 'Error: Failed to found dolibarr_htdocs_dir into XML file '.$xmlfile);
2692 }
2693
2694
2695 // Scan scripts
2696 asort($checksumconcat); // Sort list of checksum
2697 $checksumget = md5(implode(',', $checksumconcat));
2698 $checksumtoget = trim((string) $xml->dolibarr_htdocs_dir_checksum);
2699
2700 $outexpectedchecksum = ($checksumtoget ? $checksumtoget : $langs->trans("Unknown"));
2701 if ($checksumget == $checksumtoget) {
2702 if (count($file_list['added'])) {
2703 $resultcode = 'warning';
2704 $resultcomment = 'FileIntegrityIsOkButFilesWereAdded';
2705 //$outcurrentchecksum = $checksumget.' - <span class="'.$resultcode.'">'.$langs->trans("FileIntegrityIsOkButFilesWereAdded").'</span>';
2706 $outcurrentchecksum = $checksumget;
2707 } else {
2708 $resultcode = 'ok';
2709 $resultcomment = 'Success';
2710 //$outcurrentchecksum = '<span class="'.$resultcode.'">'.$checksumget.'</span>';
2711 $outcurrentchecksum = $checksumget;
2712 }
2713 } else {
2714 $resultcode = 'error';
2715 $resultcomment = 'Error';
2716 //$outcurrentchecksum = '<span class="'.$resultcode.'">'.$checksumget.'</span>';
2717 $outcurrentchecksum = $checksumget;
2718 }
2719 } else {
2720 throw new RestException(404, 'No signature file known');
2721 }
2722
2723 return array('resultcode' => $resultcode, 'resultcomment' => $resultcomment, 'expectedchecksum' => $outexpectedchecksum, 'currentchecksum' => $outcurrentchecksum, 'out' => $out);
2724 }
2725
2726
2736 public function getModules()
2737 {
2738 global $conf;
2739
2740 if (!DolibarrApiAccess::$user->admin
2741 && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_MODULES') || DolibarrApiAccess::$user->login != getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_MODULES'))) {
2742 throw new RestException(403, 'Error API open to admin users only or to the users with logins defined into constant API_LOGINS_ALLOWED_FOR_GET_MODULES');
2743 }
2744
2745 sort($conf->modules);
2746
2747 return $this->_cleanObjectDatas($conf->modules);
2748 }
2749}
$id
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
Class to manage dictionary Countries (used by imports)
Class to manage dictionary Regions.
Class to manage dictionary States (used by imports)
Class for API REST v1.
Definition api.class.php:30
_checkFilters($sqlfilters, &$error='')
Return if a $sqlfilters parameter is valid Function no more used.
_checkValForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
Definition api.class.php:82
Class to manage establishments.
Class to manage standard extra fields.
getExtrafields($attrname, $elementtype)
get Extrafield object
getShippingModes($limit=100, $page=0, $active=1, $lang='', $sqlfilters='')
Get the list of shipping methods.
getListOfContactTypes($sortfield="code", $sortorder='ASC', $limit=100, $page=0, $type='', $module='', $active=1, $lang='', $sqlfilters='')
Get the list of contacts types.
getTicketsCategories($sortfield="code", $sortorder='ASC', $limit=100, $page=0, $active=1, $lang='', $sqlfilters='')
Get the list of tickets categories.
getListOfMeasuringUnits($sortfield="rowid", $sortorder='ASC', $limit=100, $page=0, $active=1, $sqlfilters='')
Get the list of measuring units.
_cleanObjectDatas($object)
Clean sensible object datas.
getListOfStaff($sortfield="id", $sortorder='ASC', $limit=100, $page=0, $active=1, $sqlfilters='')
Get the list of staff.
getTicketsSeverities($sortfield="code", $sortorder='ASC', $limit=100, $page=0, $active=1, $lang='', $sqlfilters='')
Get the list of tickets severity.
translateLabel($object, $lang, $prefix='Country', $dict=array('dict'))
Translate the name of the object to the given language.
getCountryByISO($iso, $lang='')
Get country by Iso.
getCheckIntegrity($target)
Do a test of integrity for files and setup.
getListOfExpenseReportsTypes($sortfield="code", $sortorder='ASC', $limit=100, $page=0, $module='', $active=1, $sqlfilters='')
Get the list of Expense Report types.
__construct()
Constructor.
getListOfTowns($sortfield="zip,town", $sortorder='ASC', $limit=100, $page=0, $zipcode='', $town='', $active=1, $sqlfilters='')
Get the list of towns.
getStateByCode($code)
Get state by Code.
getListOfRegions($sortfield="code_region", $sortorder='ASC', $limit=100, $page=0, $country=0, $filter='', $sqlfilters='')
Get the list of regions.
getListOfEventTypes($sortfield="code", $sortorder='ASC', $limit=100, $page=0, $type='', $module='', $active=1, $sqlfilters='')
Get the list of events types.
getEstablishments()
Get the list of establishments.
getListOfLegalForm($sortfield="rowid", $sortorder='ASC', $limit=100, $page=0, $country=0, $active=1, $sqlfilters='')
Get the list of legal form of business.
getListOfCurrencies($multicurrency=0, $sortfield="code_iso", $sortorder='ASC', $limit=100, $page=0, $active=1, $sqlfilters='')
Get the list of currencies.
getListOfsocialNetworks($sortfield="rowid", $sortorder='ASC', $limit=100, $page=0, $active=1, $sqlfilters='')
Get the list of social networks.
_fetchCstate($id, $code='')
Get state.
getEtablishmentByID($id)
Get establishment by ID.
getConf($constantname)
Get value of a setup variables.
updateExtrafields($attrname, $elementtype, $request_data=null)
Update Extrafield object.
deleteExtrafieldsFromNames($attrname, $elementtype)
Delete extrafield.
getListOfIncoterms($sortfield="code", $sortorder='ASC', $limit=100, $page=0, $active=1, $lang='', $sqlfilters='')
Get the list of incoterms.
getCompany()
Get properties of company.
postExtrafields($attrname, $elementtype, $request_data=null)
Create Extrafield object.
getPaymentTypes($sortfield="code", $sortorder='ASC', $limit=100, $page=0, $active=1, $sqlfilters='')
Get the list of payments types.
getCountryByID($id, $lang='')
Get country by ID.
_fetchCregion($id, $code='')
Get region.
getCountryByCode($code, $lang='')
Get country by Code.
getPaymentTerms($sortfield="sortorder", $sortorder='ASC', $limit=100, $page=0, $active=1, $sqlfilters='')
Get the list of payments terms.
getOrderingOrigins($sortfield="code", $sortorder='ASC', $limit=100, $page=0, $active=1, $sqlfilters='')
Get the list of ordering origins.
getListOfActionTriggers($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $elementtype='', $lang='', $sqlfilters='')
Get the list of Action Triggers.
getListOfStates($sortfield="code_departement", $sortorder='ASC', $limit=100, $page=0, $country=0, $filter='', $sqlfilters='')
Get the list of states/provinces.
getOrderingMethods($sortfield="code", $sortorder='ASC', $limit=100, $page=0, $active=1, $sqlfilters='')
Get the list of ordering methods.
_fetchCcountry($id, $code='', $iso='', $lang='')
Get country.
getListOfExtrafields($sortfield="t.pos", $sortorder='ASC', $elementtype='', $sqlfilters='')
Get the list of extra fields.
getStateByID($id)
Get state by ID.
getAvailability($sortfield="code", $sortorder='ASC', $limit=100, $page=0, $active=1, $sqlfilters='')
Get the list of delivery times.
getTicketsTypes($sortfield="code", $sortorder='ASC', $limit=100, $page=0, $active=1, $lang='', $sqlfilters='')
Get the list of tickets types.
getRegionByCode($code)
Get region by Code.
getListOfCountries($sortfield="code", $sortorder='ASC', $limit=100, $page=0, $filter='', $lang='', $sqlfilters='')
Get the list of countries.
getRegionByID($id)
Get region by ID.
getListOfCivilities($sortfield="code", $sortorder='ASC', $limit=100, $page=0, $module='', $active=1, $lang='', $sqlfilters='')
Get the list of civilities.
getModules()
Get list of enabled modules.
Class to manage translations.
getFilesUpdated(&$file_list, SimpleXMLElement $dir, $path='', $pathref='', &$checksumconcat=array())
Function to get list of updated or modified files.
dol_filemtime($pathoffile)
Return time of a file.
dol_filesize($pathoffile)
Return size of a file.
dol_is_file($pathoffile)
Return if path is a file.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:63
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
isASecretKey($keyname)
Return if string has a name dedicated to store a secret.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
jsonOrUnserialize($stringtodecode)
Decode an encode string.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getURLContent($url, $postorget='GET', $param='', $followlocation=1, $addheaders=array(), $allowedschemes=array('http', 'https'), $localurl=0, $ssl_verifypeer=-1)
Function to get a content from an URL (use proxy if proxy defined).
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79