dolibarr 22.0.5
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-2025 MDW <mdeweerd@users.noreply.github.com>
10 * Copyright (C) 2025 Charlene Benke <charlene@patas-monkey.com>
11 *
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 */
26
27use Luracast\Restler\RestException;
28
29require_once DOL_DOCUMENT_ROOT.'/main.inc.php';
30require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php';
31require_once DOL_DOCUMENT_ROOT.'/core/class/cstate.class.php';
32require_once DOL_DOCUMENT_ROOT.'/core/class/cregion.class.php';
33require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php';
34require_once DOL_DOCUMENT_ROOT.'/hrm/class/establishment.class.php';
35
42class Setup extends DolibarrApi
43{
47 private $translations = null;
48
52 public function __construct()
53 {
54 global $db;
55 $this->db = $db;
56 }
57
77 public function getListOfActionTriggers($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $elementtype = '', $lang = '', $sqlfilters = '')
78 {
79 $list = array();
80
81 if ($elementtype == 'thirdparty') {
82 $elementtype = 'societe';
83 }
84 if ($elementtype == 'contact') {
85 $elementtype = 'socpeople';
86 }
87
88 $sql = "SELECT t.rowid as id, t.elementtype, t.code, t.contexts, t.label, t.description, t.rang";
89 $sql .= " FROM ".MAIN_DB_PREFIX."c_action_trigger as t";
90 $sql .= " WHERE 1=1";
91 if (!empty($elementtype)) {
92 $sql .= " AND t.elementtype = '".$this->db->escape($elementtype)."'";
93 }
94 // Add sql filters
95 if ($sqlfilters) {
96 $errormessage = '';
97 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
98 if ($errormessage) {
99 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
100 }
101 }
102
103 $sql .= $this->db->order($sortfield, $sortorder);
104
105 if ($limit) {
106 if ($page < 0) {
107 $page = 0;
108 }
109 $offset = $limit * $page;
110
111 $sql .= $this->db->plimit($limit, $offset);
112 }
113
114 $result = $this->db->query($sql);
115 if ($result) {
116 $num = $this->db->num_rows($result);
117 $min = min($num, ($limit <= 0 ? $num : $limit));
118 for ($i = 0; $i < $min; $i++) {
119 $type = $this->db->fetch_object($result);
120 $this->translateLabel($type, $lang, 'Notify_', array('other'));
121 $list[] = $type;
122 }
123 } else {
124 throw new RestException(503, 'Error when retrieving list of action triggers : '.$this->db->lasterror());
125 }
126
127 return $list;
128 }
129
150 public function getOrderingMethods($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
151 {
152 $list = array();
153
154 if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) {
155 throw new RestException(403);
156 }
157
158 $sql = "SELECT rowid, code, libelle as label, module";
159 $sql .= " FROM ".MAIN_DB_PREFIX."c_input_method as t";
160 $sql .= " WHERE t.active = ".((int) $active);
161 // Add sql filters
162 if ($sqlfilters) {
163 $errormessage = '';
164 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
165 if ($errormessage) {
166 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
167 }
168 }
169
170
171 $sql .= $this->db->order($sortfield, $sortorder);
172
173 if ($limit) {
174 if ($page < 0) {
175 $page = 0;
176 }
177 $offset = $limit * $page;
178
179 $sql .= $this->db->plimit($limit, $offset);
180 }
181
182 $result = $this->db->query($sql);
183
184 if ($result) {
185 $num = $this->db->num_rows($result);
186 $min = min($num, ($limit <= 0 ? $num : $limit));
187 for ($i = 0; $i < $min; $i++) {
188 $list[] = $this->db->fetch_object($result);
189 }
190 } else {
191 throw new RestException(503, $this->db->lasterror());
192 }
193
194 return $list;
195 }
196
216 public function getOrderingOrigins($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
217 {
218 $list = array();
219
220 if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) {
221 throw new RestException(403);
222 }
223
224 $sql = "SELECT rowid, code, label, module";
225 $sql .= " FROM ".MAIN_DB_PREFIX."c_input_reason as t";
226 $sql .= " WHERE t.active = ".((int) $active);
227 // Add sql filters
228 if ($sqlfilters) {
229 $errormessage = '';
230 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
231 if ($errormessage) {
232 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
233 }
234 }
235
236
237 $sql .= $this->db->order($sortfield, $sortorder);
238
239 if ($limit) {
240 if ($page < 0) {
241 $page = 0;
242 }
243 $offset = $limit * $page;
244
245 $sql .= $this->db->plimit($limit, $offset);
246 }
247
248 $result = $this->db->query($sql);
249
250 if ($result) {
251 $num = $this->db->num_rows($result);
252 $min = min($num, ($limit <= 0 ? $num : $limit));
253 for ($i = 0; $i < $min; $i++) {
254 $list[] = $this->db->fetch_object($result);
255 }
256 } else {
257 throw new RestException(503, $this->db->lasterror());
258 }
259
260 return $list;
261 }
262
283 public function getPaymentTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
284 {
285 $list = array();
286
287 if (!DolibarrApiAccess::$user->hasRight('propal', 'lire') && !DolibarrApiAccess::$user->hasRight('commande', 'lire') && !DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
288 throw new RestException(403);
289 }
290
291 $sql = "SELECT id, code, type, libelle as label, module";
292 $sql .= " FROM ".MAIN_DB_PREFIX."c_paiement as t";
293 $sql .= " WHERE t.entity IN (".getEntity('c_paiement').")";
294 $sql .= " AND t.active = ".((int) $active);
295 // Add sql filters
296 if ($sqlfilters) {
297 $errormessage = '';
298 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
299 if ($errormessage) {
300 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
301 }
302 }
303
304
305 $sql .= $this->db->order($sortfield, $sortorder);
306
307 if ($limit) {
308 if ($page < 0) {
309 $page = 0;
310 }
311 $offset = $limit * $page;
312
313 $sql .= $this->db->plimit($limit, $offset);
314 }
315
316 $result = $this->db->query($sql);
317
318 if ($result) {
319 $num = $this->db->num_rows($result);
320 $min = min($num, ($limit <= 0 ? $num : $limit));
321 for ($i = 0; $i < $min; $i++) {
322 $list[] = $this->db->fetch_object($result);
323 }
324 } else {
325 throw new RestException(503, $this->db->lasterror());
326 }
327
328 return $list;
329 }
351 public function getListOfRegions($sortfield = "code_region", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $filter = '', $sqlfilters = '')
352 {
353 $list = array();
354
355 // Note: The filter is not applied in the SQL request because it must
356 // be applied to the translated names, not to the names in database.
357 $sql = "SELECT t.rowid FROM ".MAIN_DB_PREFIX."c_regions as t";
358 $sql .= " WHERE 1 = 1";
359 if ($country) {
360 $sql .= " AND t.fk_pays = ".((int) $country);
361 }
362 // Add sql filters
363 if ($sqlfilters) {
364 $errormessage = '';
365 if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
366 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
367 }
368 $regexstring = '\‍(([^:\'\‍(\‍)]+:[^:\'\‍(\‍)]+:[^\‍(\‍)]+)\‍)';
369 $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
370 }
371
372 $sql .= $this->db->order($sortfield, $sortorder);
373
374 if ($limit) {
375 if ($page < 0) {
376 $page = 0;
377 }
378 $offset = $limit * $page;
379
380 $sql .= $this->db->plimit($limit, $offset);
381 }
382
383 $result = $this->db->query($sql);
384
385 if ($result) {
386 $num = $this->db->num_rows($result);
387 $min = min($num, ($limit <= 0 ? $num : $limit));
388 for ($i = 0; $i < $min; $i++) {
389 $obj = $this->db->fetch_object($result);
390 $region = new Cregion($this->db);
391 if ($region->fetch($obj->rowid) > 0) {
392 if (empty($filter) || stripos($region->name, $filter) !== false) {
393 $list[] = $this->_cleanObjectDatas($region);
394 }
395 }
396 }
397 } else {
398 throw new RestException(503, 'Error when retrieving list of regions');
399 }
400
401 return $list;
402 }
403
417 public function getRegionByID($id)
418 {
419 return $this->_fetchCregion($id, '');
420 }
421
435 public function getRegionByCode($code)
436 {
437 return $this->_fetchCregion(0, $code);
438 }
439
464 public function getListOfStates($sortfield = "code_departement", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $filter = '', $sqlfilters = '')
465 {
466 $list = array();
467
468 // Note: The filter is not applied in the SQL request because it must
469 // be applied to the translated names, not to the names in database.
470 $sql = "SELECT t.rowid FROM ".MAIN_DB_PREFIX."c_departements as t";
471 if ($country) {
472 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_regions as d ON t.fk_region = d.code_region";
473 }
474 $sql .= " WHERE 1 = 1";
475 if ($country) {
476 $sql .= " AND d.fk_pays = ".((int) $country);
477 }
478 // Add sql filters
479 if ($sqlfilters) {
480 $errormessage = '';
481 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
482 if ($errormessage) {
483 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
484 }
485 }
486
487 $sql .= $this->db->order($sortfield, $sortorder);
488
489 if ($limit) {
490 if ($page < 0) {
491 $page = 0;
492 }
493 $offset = $limit * $page;
494
495 $sql .= $this->db->plimit($limit, $offset);
496 }
497
498 $result = $this->db->query($sql);
499
500 if ($result) {
501 $num = $this->db->num_rows($result);
502 $min = min($num, ($limit <= 0 ? $num : $limit));
503 for ($i = 0; $i < $min; $i++) {
504 $obj = $this->db->fetch_object($result);
505 $state = new Cstate($this->db);
506 if ($state->fetch($obj->rowid) > 0) {
507 if (empty($filter) || stripos($state->label, $filter) !== false) {
508 $list[] = $this->_cleanObjectDatas($state);
509 }
510 }
511 }
512 } else {
513 throw new RestException(503, 'Error when retrieving list of states');
514 }
515
516 return $list;
517 }
518
532 public function getStateByID($id)
533 {
534 return $this->_fetchCstate($id, '');
535 }
536
550 public function getStateByCode($code)
551 {
552 return $this->_fetchCstate(0, $code);
553 }
554
579 public function getListOfCountries($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $lang = '', $sqlfilters = '')
580 {
581 $list = array();
582
583 // Note: The filter is not applied in the SQL request because it must
584 // be applied to the translated names, not to the names in database.
585 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_country as t";
586 $sql .= " WHERE 1 = 1";
587 // Add sql filters
588 if ($sqlfilters) {
589 $errormessage = '';
590 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
591 if ($errormessage) {
592 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
593 }
594 }
595
596 $sql .= $this->db->order($sortfield, $sortorder);
597
598 if ($limit) {
599 if ($page < 0) {
600 $page = 0;
601 }
602 $offset = $limit * $page;
603
604 $sql .= $this->db->plimit($limit, $offset);
605 }
606
607 $result = $this->db->query($sql);
608
609 if ($result) {
610 $num = $this->db->num_rows($result);
611 $min = min($num, ($limit <= 0 ? $num : $limit));
612 for ($i = 0; $i < $min; $i++) {
613 $obj = $this->db->fetch_object($result);
614 $country = new Ccountry($this->db);
615 if ($country->fetch($obj->rowid) > 0) {
616 // Translate the name of the country if needed
617 // and then apply the filter if there is one.
618 $this->translateLabel($country, $lang, 'Country');
619
620 if (empty($filter) || stripos($country->label, $filter) !== false) {
621 $list[] = $this->_cleanObjectDatas($country);
622 }
623 }
624 }
625 } else {
626 throw new RestException(503, 'Error when retrieving list of countries');
627 }
628
629 return $list;
630 }
631
646 public function getCountryByID($id, $lang = '')
647 {
648 return $this->_fetchCcountry($id, '', '', $lang);
649 }
650
665 public function getCountryByCode($code, $lang = '')
666 {
667 return $this->_fetchCcountry(0, $code, '', $lang);
668 }
669
682 public function getCountryByISO($iso, $lang = '')
683 {
684 return $this->_fetchCcountry(0, '', $iso, $lang);
685 }
686
698 private function _fetchCregion($id, $code = '')
699 {
700 $region = new Cregion($this->db);
701
702 $result = $region->fetch($id, (int) $code);
703 if ($result < 0) {
704 throw new RestException(503, 'Error when retrieving region : '.$region->error);
705 } elseif ($result == 0) {
706 throw new RestException(404, 'Region not found');
707 }
708
709 return $this->_cleanObjectDatas($region);
710 }
711
723 private function _fetchCstate($id, $code = '')
724 {
725 $state = new Cstate($this->db);
726
727 $result = $state->fetch($id, $code);
728 if ($result < 0) {
729 throw new RestException(503, 'Error when retrieving state : '.$state->error);
730 } elseif ($result == 0) {
731 throw new RestException(404, 'State not found');
732 }
733
734 return $this->_cleanObjectDatas($state);
735 }
736
750 private function _fetchCcountry($id, $code = '', $iso = '', $lang = '')
751 {
752 $country = new Ccountry($this->db);
753
754 $result = $country->fetch($id, $code, $iso);
755
756 if ($result < 0) {
757 throw new RestException(503, 'Error when retrieving country : '.$country->error);
758 } elseif ($result == 0) {
759 throw new RestException(404, 'Country not found');
760 }
761
762 $this->translateLabel($country, $lang, 'Country');
763
764 return $this->_cleanObjectDatas($country);
765 }
766
787 public function getAvailability($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
788 {
789 $list = array();
790
791 if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) {
792 throw new RestException(403);
793 }
794
795 $sql = "SELECT rowid, code, label";
796 $sql .= " FROM ".MAIN_DB_PREFIX."c_availability as t";
797 $sql .= " WHERE t.active = ".((int) $active);
798 // Add sql filters
799 if ($sqlfilters) {
800 $errormessage = '';
801 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
802 if ($errormessage) {
803 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
804 }
805 }
806
807
808 $sql .= $this->db->order($sortfield, $sortorder);
809
810 if ($limit) {
811 if ($page < 0) {
812 $page = 0;
813 }
814 $offset = $limit * $page;
815
816 $sql .= $this->db->plimit($limit, $offset);
817 }
818
819 $result = $this->db->query($sql);
820
821 if ($result) {
822 $num = $this->db->num_rows($result);
823 $min = min($num, ($limit <= 0 ? $num : $limit));
824 for ($i = 0; $i < $min; $i++) {
825 $list[] = $this->db->fetch_object($result);
826 }
827 } else {
828 throw new RestException(503, $this->db->lasterror());
829 }
830
831 return $list;
832 }
833
834 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
841 protected function _cleanObjectDatas($object)
842 {
843 // phpcs:enable
844 $object = parent::_cleanObjectDatas($object);
845
846 unset($object->error);
847 unset($object->errors);
848
849 return $object;
850 }
851
861 private function translateLabel($object, $lang, $prefix = 'Country', $dict = array('dict'))
862 {
863 if (!empty($lang)) {
864 // Load the translations if this is a new language.
865 if ($this->translations == null || $this->translations->getDefaultLang() !== $lang) {
866 global $conf;
867 $this->translations = new Translate('', $conf);
868 $this->translations->setDefaultLang($lang);
869 $this->translations->loadLangs($dict);
870 }
871 if ($object->code) {
872 $key = $prefix.$object->code;
873
874 $translation = $this->translations->trans($key);
875 if ($translation != $key) {
876 $object->label = html_entity_decode($translation);
877 }
878 }
879 }
880 }
881
902 public function getListOfEventTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $active = 1, $sqlfilters = '')
903 {
904 $list = array();
905
906 $sql = "SELECT id, code, type, libelle as label, module";
907 $sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm as t";
908 $sql .= " WHERE t.active = ".((int) $active);
909 if ($type) {
910 $sql .= " AND t.type LIKE '%".$this->db->escape($type)."%'";
911 }
912 if ($module) {
913 $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
914 }
915 // Add sql filters
916 if ($sqlfilters) {
917 $errormessage = '';
918 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
919 if ($errormessage) {
920 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
921 }
922 }
923
924
925 $sql .= $this->db->order($sortfield, $sortorder);
926
927 if ($limit) {
928 if ($page < 0) {
929 $page = 0;
930 }
931 $offset = $limit * $page;
932
933 $sql .= $this->db->plimit($limit, $offset);
934 }
935
936 $result = $this->db->query($sql);
937
938 if ($result) {
939 $num = $this->db->num_rows($result);
940 $min = min($num, ($limit <= 0 ? $num : $limit));
941 for ($i = 0; $i < $min; $i++) {
942 $list[] = $this->db->fetch_object($result);
943 }
944 } else {
945 throw new RestException(503, 'Error when retrieving list of events types : '.$this->db->lasterror());
946 }
947
948 return $list;
949 }
950
951
971 public function getListOfExpenseReportsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $module = '', $active = 1, $sqlfilters = '')
972 {
973 $list = array();
974
975 $sql = "SELECT id, code, label, accountancy_code, active, module, position";
976 $sql .= " FROM ".MAIN_DB_PREFIX."c_type_fees as t";
977 $sql .= " WHERE t.active = ".((int) $active);
978 if ($module) {
979 $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
980 }
981 // Add sql filters
982 if ($sqlfilters) {
983 $errormessage = '';
984 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
985 if ($errormessage) {
986 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
987 }
988 }
989
990
991 $sql .= $this->db->order($sortfield, $sortorder);
992
993 if ($limit) {
994 if ($page < 0) {
995 $page = 0;
996 }
997 $offset = $limit * $page;
998
999 $sql .= $this->db->plimit($limit, $offset);
1000 }
1001
1002 $result = $this->db->query($sql);
1003
1004 if ($result) {
1005 $num = $this->db->num_rows($result);
1006 $min = min($num, ($limit <= 0 ? $num : $limit));
1007 for ($i = 0; $i < $min; $i++) {
1008 $list[] = $this->db->fetch_object($result);
1009 }
1010 } else {
1011 throw new RestException(503, 'Error when retrieving list of expense report types : '.$this->db->lasterror());
1012 }
1013
1014 return $list;
1015 }
1016
1017
1039 public function getListOfContactTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $active = 1, $lang = '', $sqlfilters = '')
1040 {
1041 $list = array();
1042
1043 $sql = "SELECT rowid, code, element as type, libelle as label, source, module, position";
1044 $sql .= " FROM ".MAIN_DB_PREFIX."c_type_contact as t";
1045 $sql .= " WHERE t.active = ".((int) $active);
1046 if ($type) {
1047 $sql .= " AND t.element LIKE '%".$this->db->escape($type)."%'";
1048 }
1049 if ($module) {
1050 $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
1051 }
1052 // Add sql filters
1053 if ($sqlfilters) {
1054 $errormessage = '';
1055 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1056 if ($errormessage) {
1057 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1058 }
1059 }
1060
1061
1062 $sql .= $this->db->order($sortfield, $sortorder);
1063
1064 if ($limit) {
1065 if ($page < 0) {
1066 $page = 0;
1067 }
1068 $offset = $limit * $page;
1069
1070 $sql .= $this->db->plimit($limit, $offset);
1071 }
1072
1073 $result = $this->db->query($sql);
1074
1075 if ($result) {
1076 $num = $this->db->num_rows($result);
1077 $min = min($num, ($limit <= 0 ? $num : $limit));
1078 for ($i = 0; $i < $min; $i++) {
1079 $contact_type = $this->db->fetch_object($result);
1080 $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"));
1081 $list[] = $contact_type;
1082 }
1083 } else {
1084 throw new RestException(503, 'Error when retrieving list of contacts types : '.$this->db->lasterror());
1085 }
1086
1087 return $list;
1088 }
1089
1110 public function getListOfCivilities($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $module = '', $active = 1, $lang = '', $sqlfilters = '')
1111 {
1112 $list = array();
1113
1114 $sql = "SELECT rowid, code, label, module";
1115 $sql .= " FROM ".MAIN_DB_PREFIX."c_civility as t";
1116 $sql .= " WHERE t.active = ".((int) $active);
1117 if ($module) {
1118 $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
1119 }
1120 // Add sql filters
1121 if ($sqlfilters) {
1122 $errormessage = '';
1123 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1124 if ($errormessage) {
1125 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1126 }
1127 }
1128
1129
1130 $sql .= $this->db->order($sortfield, $sortorder);
1131
1132 if ($limit) {
1133 if ($page < 0) {
1134 $page = 0;
1135 }
1136 $offset = $limit * $page;
1137
1138 $sql .= $this->db->plimit($limit, $offset);
1139 }
1140
1141 $result = $this->db->query($sql);
1142
1143 if ($result) {
1144 $num = $this->db->num_rows($result);
1145 $min = min($num, ($limit <= 0 ? $num : $limit));
1146 for ($i = 0; $i < $min; $i++) {
1147 $civility = $this->db->fetch_object($result);
1148 $this->translateLabel($civility, $lang, 'Civility', array('dict'));
1149 $list[] = $civility;
1150 }
1151 } else {
1152 throw new RestException(503, 'Error when retrieving list of civility : '.$this->db->lasterror());
1153 }
1154
1155 return $list;
1156 }
1157
1177 public function getListOfCurrencies($multicurrency = 0, $sortfield = "code_iso", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1178 {
1179 $list = array();
1180 $sql = "SELECT t.code_iso, t.label, t.unicode";
1181 if (!empty($multicurrency)) {
1182 $sql .= " , cr.date_sync, cr.rate ";
1183 }
1184 $sql .= " FROM ".MAIN_DB_PREFIX."c_currencies as t";
1185 if (!empty($multicurrency)) {
1186 $sql .= " JOIN ".MAIN_DB_PREFIX."multicurrency as m ON m.code=t.code_iso";
1187 $sql .= " JOIN ".MAIN_DB_PREFIX."multicurrency_rate as cr ON (m.rowid = cr.fk_multicurrency)";
1188 }
1189 $sql .= " WHERE t.active = ".((int) $active);
1190 if (!empty($multicurrency)) {
1191 $sql .= " AND m.entity IN (".getEntity('multicurrency').")";
1192 if (!empty($multicurrency) && $multicurrency != 2) {
1193 $sql .= " AND cr.date_sync = (SELECT MAX(cr2.date_sync) FROM ".MAIN_DB_PREFIX."multicurrency_rate AS cr2 WHERE cr2.fk_multicurrency = m.rowid)";
1194 }
1195 }
1196
1197 // Add sql filters
1198 if ($sqlfilters) {
1199 $errormessage = '';
1200 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1201 if ($errormessage) {
1202 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1203 }
1204 }
1205
1206
1207 $sql .= $this->db->order($sortfield, $sortorder);
1208
1209 if ($limit) {
1210 if ($page < 0) {
1211 $page = 0;
1212 }
1213 $offset = $limit * $page;
1214
1215 $sql .= $this->db->plimit($limit, $offset);
1216 }
1217
1218 $result = $this->db->query($sql);
1219
1220 if ($result) {
1221 $num = $this->db->num_rows($result);
1222 $min = min($num, ($limit <= 0 ? $num : $limit));
1223 for ($i = 0; $i < $min; $i++) {
1224 $list[] = $this->db->fetch_object($result);
1225 }
1226 } else {
1227 throw new RestException(503, 'Error when retrieving list of currency : '.$this->db->lasterror());
1228 }
1229
1230 return $list;
1231 }
1232
1249 public function getListOfExtrafields($sortfield = "t.pos", $sortorder = 'ASC', $elementtype = '', $sqlfilters = '')
1250 {
1251 $list = array();
1252
1253 if (!DolibarrApiAccess::$user->admin
1254 && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_EXTRAFIELDS') || DolibarrApiAccess::$user->login != getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_EXTRAFIELDS'))) {
1255 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');
1256 }
1257
1258 if ($elementtype == 'thirdparty') {
1259 $elementtype = 'societe';
1260 }
1261 if ($elementtype == 'contact') {
1262 $elementtype = 'socpeople';
1263 }
1264
1265 $sql = "SELECT t.rowid as id, t.name, t.entity, t.elementtype, t.label, t.type, t.size, t.fieldcomputed, t.fielddefault,";
1266 $sql .= " t.fieldunique, t.fieldrequired, t.perms, t.enabled, t.pos, t.alwayseditable, t.param, t.list, t.printable,";
1267 $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";
1268 $sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
1269 $sql .= " WHERE t.entity IN (".getEntity('extrafields').")";
1270 if (!empty($elementtype)) {
1271 $sql .= " AND t.elementtype = '".$this->db->escape($elementtype)."'";
1272 }
1273 // Add sql filters
1274 if ($sqlfilters) {
1275 $errormessage = '';
1276 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1277 if ($errormessage) {
1278 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1279 }
1280 }
1281
1282 $sql .= $this->db->order($sortfield, $sortorder);
1283
1284 $resql = $this->db->query($sql);
1285 if ($resql) {
1286 if ($this->db->num_rows($resql)) {
1287 while ($tab = $this->db->fetch_object($resql)) {
1288 // New usage
1289 $list[$tab->elementtype][$tab->name]['id'] = $tab->id;
1290 $list[$tab->elementtype][$tab->name]['type'] = $tab->type;
1291 $list[$tab->elementtype][$tab->name]['label'] = $tab->label;
1292 $list[$tab->elementtype][$tab->name]['size'] = $tab->size;
1293 $list[$tab->elementtype][$tab->name]['elementtype'] = $tab->elementtype;
1294 $list[$tab->elementtype][$tab->name]['default'] = $tab->fielddefault;
1295 $list[$tab->elementtype][$tab->name]['computed'] = $tab->fieldcomputed;
1296 $list[$tab->elementtype][$tab->name]['unique'] = $tab->fieldunique;
1297 $list[$tab->elementtype][$tab->name]['required'] = $tab->fieldrequired;
1298 $list[$tab->elementtype][$tab->name]['param'] = ($tab->param ? jsonOrUnserialize($tab->param) : ''); // This may be a string encoded with serialise() or json_encode()
1299 $list[$tab->elementtype][$tab->name]['pos'] = $tab->pos;
1300 $list[$tab->elementtype][$tab->name]['alwayseditable'] = $tab->alwayseditable;
1301 $list[$tab->elementtype][$tab->name]['perms'] = $tab->perms;
1302 $list[$tab->elementtype][$tab->name]['list'] = $tab->list;
1303 $list[$tab->elementtype][$tab->name]['printable'] = $tab->printable;
1304 $list[$tab->elementtype][$tab->name]['totalizable'] = $tab->totalizable;
1305 $list[$tab->elementtype][$tab->name]['langs'] = $tab->langs;
1306 $list[$tab->elementtype][$tab->name]['help'] = $tab->help;
1307 $list[$tab->elementtype][$tab->name]['css'] = $tab->css;
1308 $list[$tab->elementtype][$tab->name]['cssview'] = $tab->cssview;
1309 $list[$tab->elementtype][$tab->name]['csslist'] = $tab->csslist;
1310 $list[$tab->elementtype][$tab->name]['fk_user_author'] = $tab->fk_user_author;
1311 $list[$tab->elementtype][$tab->name]['fk_user_modif'] = $tab->fk_user_modif;
1312 $list[$tab->elementtype][$tab->name]['datec'] = $tab->datec;
1313 $list[$tab->elementtype][$tab->name]['tms'] = $tab->tms;
1314 }
1315 }
1316 } else {
1317 throw new RestException(503, 'Error when retrieving list of extra fields : '.$this->db->lasterror());
1318 }
1319
1320 return $list;
1321 }
1322
1334 public function deleteExtrafieldsFromNames($attrname, $elementtype)
1335 {
1336 if (!DolibarrApiAccess::$user->admin) {
1337 throw new RestException(403, 'Only an admin user can delete an extrafield by attrname and elementtype');
1338 }
1339
1340 $extrafields = new ExtraFields($this->db);
1341
1342 $result = $extrafields->fetch_name_optionals_label($elementtype, false, $attrname);
1343 if (!$result) {
1344 throw new RestException(404, 'Extrafield not found from attrname and elementtype');
1345 }
1346
1347 if (!$extrafields->delete($attrname, $elementtype)) {
1348 throw new RestException(500, 'Error when delete extrafield : '.$extrafields->error);
1349 }
1350
1351 return array(
1352 'success' => array(
1353 'code' => 200,
1354 'message' => 'Extrafield deleted from attrname and elementtype'
1355 )
1356 );
1357 }
1358
1359
1360
1373 public function getExtrafields($attrname, $elementtype)
1374 {
1375 $answer = array();
1376
1377 if (!DolibarrApiAccess::$user->admin) {
1378 throw new RestException(403, 'Only an admin user can get list of extrafields');
1379 }
1380
1381 if ($elementtype == 'thirdparty') {
1382 $elementtype = 'societe';
1383 }
1384 if ($elementtype == 'contact') {
1385 $elementtype = 'socpeople';
1386 }
1387
1388 $sql = "SELECT t.rowid as id, t.name, t.entity, t.elementtype, t.label, t.type, t.size, t.fieldcomputed, t.fielddefault,";
1389 $sql .= " t.fieldunique, t.fieldrequired, t.perms, t.enabled, t.pos, t.alwayseditable, t.param, t.list, t.printable,";
1390 $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";
1391 $sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
1392 $sql .= " WHERE t.entity IN (".getEntity('extrafields').")";
1393 $sql .= " AND t.elementtype = '".$this->db->escape($elementtype)."'";
1394 $sql .= " AND t.name = '".$this->db->escape($attrname)."'";
1395
1396 $resql = $this->db->query($sql);
1397 if ($resql) {
1398 if ($this->db->num_rows($resql)) {
1399 while ($tab = $this->db->fetch_object($resql)) {
1400 // New usage
1401 $answer[$tab->elementtype][$tab->name]['id'] = $tab->id;
1402 $answer[$tab->elementtype][$tab->name]['type'] = $tab->type;
1403 $answer[$tab->elementtype][$tab->name]['label'] = $tab->label;
1404 $answer[$tab->elementtype][$tab->name]['size'] = $tab->size;
1405 $answer[$tab->elementtype][$tab->name]['elementtype'] = $tab->elementtype;
1406 $answer[$tab->elementtype][$tab->name]['default'] = $tab->fielddefault;
1407 $answer[$tab->elementtype][$tab->name]['computed'] = $tab->fieldcomputed;
1408 $answer[$tab->elementtype][$tab->name]['unique'] = $tab->fieldunique;
1409 $answer[$tab->elementtype][$tab->name]['required'] = $tab->fieldrequired;
1410 $answer[$tab->elementtype][$tab->name]['param'] = ($tab->param ? jsonOrUnserialize($tab->param) : ''); // This may be a string encoded with serialise() or json_encode()
1411 $answer[$tab->elementtype][$tab->name]['pos'] = $tab->pos;
1412 $answer[$tab->elementtype][$tab->name]['alwayseditable'] = $tab->alwayseditable;
1413 $answer[$tab->elementtype][$tab->name]['perms'] = $tab->perms;
1414 $answer[$tab->elementtype][$tab->name]['list'] = $tab->list;
1415 $answer[$tab->elementtype][$tab->name]['printable'] = $tab->printable;
1416 $answer[$tab->elementtype][$tab->name]['totalizable'] = $tab->totalizable;
1417 $answer[$tab->elementtype][$tab->name]['langs'] = $tab->langs;
1418 $answer[$tab->elementtype][$tab->name]['help'] = $tab->help;
1419 $answer[$tab->elementtype][$tab->name]['css'] = $tab->css;
1420 $answer[$tab->elementtype][$tab->name]['cssview'] = $tab->cssview;
1421 $answer[$tab->elementtype][$tab->name]['csslist'] = $tab->csslist;
1422 $answer[$tab->elementtype][$tab->name]['fk_user_author'] = $tab->fk_user_author;
1423 $answer[$tab->elementtype][$tab->name]['fk_user_modif'] = $tab->fk_user_modif;
1424 $answer[$tab->elementtype][$tab->name]['datec'] = $tab->datec;
1425 $answer[$tab->elementtype][$tab->name]['tms'] = $tab->tms;
1426 }
1427 } else {
1428 throw new RestException(404, 'Extrafield not found from attrname and elementtype');
1429 }
1430 } else {
1431 throw new RestException(503, 'Error when retrieving list of extra fields : '.$this->db->lasterror());
1432 }
1433
1434 return $answer;
1435 }
1436
1451 public function postExtrafields($attrname, $elementtype, $request_data = null)
1452 {
1453 if (!DolibarrApiAccess::$user->admin) {
1454 throw new RestException(403, 'Only an admin user can create an extrafield');
1455 }
1456
1457 $extrafields = new ExtraFields($this->db);
1458
1459 $result = $extrafields->fetch_name_optionals_label($elementtype, false, $attrname);
1460 if ($result) {
1461 throw new RestException(409, 'Duplicate extrafield already found from attrname and elementtype');
1462 }
1463
1464 // Check mandatory fields is not working despise being a modified copy from api_thirdparties.class.php
1465 // $result = $this->_validateExtrafields($request_data, $extrafields);
1466
1467 foreach ($request_data as $field => $value) {
1468 $extrafields->$field = $this->_checkValForAPI($field, $value, $extrafields);
1469 }
1470
1471 $entity = DolibarrApiAccess::$user->entity;
1472 if (empty($entity)) {
1473 $entity = 1;
1474 }
1475
1476 // built in validation
1477 $enabled = 1; // hardcoded because it seems to always be 1 in every row in the database
1478
1479 if ($request_data['label']) {
1480 $label = $request_data['label'];
1481 } else {
1482 throw new RestException(400, "label field absent in json at root level");
1483 }
1484
1485 $alwayseditable = $request_data['alwayseditable'];
1486 $default_value = $request_data['default'];
1487 $totalizable = $request_data['totalizable'];
1488 $printable = $request_data['printable'];
1489 $required = $request_data['required'];
1490 $langfile = $request_data['langfile'];
1491 $computed = $request_data['computed'];
1492 $unique = $request_data['unique'];
1493 $param = $request_data['param'];
1494 $perms = $request_data['perms'];
1495 $size = $request_data['size'];
1496 $type = $request_data['type'];
1497 $list = $request_data['list'];
1498 $help = $request_data['help'];
1499 $pos = $request_data['pos'];
1500 $moreparams = array();
1501
1502 if (0 > $extrafields->addExtraField($attrname, $label, $type, (int) $pos, $size, $elementtype, (int) $unique, (int) $required, $default_value, $param, (int) $alwayseditable, $perms, $list, $help, $computed, (string) $entity, $langfile, (string) $enabled, (int) $totalizable, (int) $printable, $moreparams)) {
1503 throw new RestException(500, 'Error creating extrafield', array_merge(array($extrafields->errno), $extrafields->errors));
1504 }
1505
1506 $sql = "SELECT t.rowid as id";
1507 $sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
1508 $sql .= " WHERE elementtype = '".$this->db->escape($elementtype)."'";
1509 $sql .= " AND name = '".$this->db->escape($attrname)."'";
1510
1511 $resql = $this->db->query($sql);
1512 if ($resql) {
1513 if ($this->db->num_rows($resql)) {
1514 $tab = $this->db->fetch_object($resql);
1515 $id = (int) $tab->id;
1516 } else {
1517 $id = (int) -1;
1518 }
1519 } else {
1520 $id = (int) -2;
1521 }
1522
1523 return $id;
1524 }
1525
1540 public function updateExtrafields($attrname, $elementtype, $request_data = null)
1541 {
1542 if (!DolibarrApiAccess::$user->admin) {
1543 throw new RestException(403, 'Only an admin user can create an extrafield');
1544 }
1545
1546 $extrafields = new ExtraFields($this->db);
1547
1548 $result = $extrafields->fetch_name_optionals_label($elementtype, false, $attrname);
1549 if (!$result) {
1550 throw new RestException(404, 'Extrafield not found from attrname and elementtype');
1551 }
1552
1553 foreach ($request_data as $field => $value) {
1554 $extrafields->$field = $this->_checkValForAPI($field, $value, $extrafields);
1555 }
1556
1557 $entity = DolibarrApiAccess::$user->entity;
1558 if (empty($entity)) {
1559 $entity = 1;
1560 }
1561
1562 // built in validation
1563 $enabled = 1; // hardcoded because it seems to always be 1 in every row in the database
1564 if ($request_data['label']) {
1565 $label = $request_data['label'];
1566 } else {
1567 throw new RestException(400, "label field absent in json at root level");
1568 }
1569
1570 $alwayseditable = $request_data['alwayseditable'];
1571 $default_value = $request_data['default'];
1572 $totalizable = $request_data['totalizable'];
1573 $printable = $request_data['printable'];
1574 $required = $request_data['required'];
1575 $langfile = $request_data['langfile'];
1576 $computed = $request_data['computed'];
1577 $unique = $request_data['unique'];
1578 $param = $request_data['param'];
1579 $perms = $request_data['perms'];
1580 $size = $request_data['size'];
1581 $type = $request_data['type'];
1582 $list = $request_data['list'];
1583 $help = $request_data['help'];
1584 $pos = $request_data['pos'];
1585 $moreparams = array();
1586
1587 if (0 > $extrafields->updateExtraField($attrname, $label, $type, (int) $pos, $size, $elementtype, (int) $unique, (int) $required, $default_value, $param, (int) $alwayseditable, $perms, $list, $help, $computed, (string) $entity, $langfile, (string) $enabled, (int) $totalizable, (int) $printable, $moreparams)) {
1588 throw new RestException(500, 'Error updating extrafield', array_merge(array($extrafields->errno), $extrafields->errors));
1589 }
1590
1591 $sql = "SELECT t.rowid as id";
1592 $sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
1593 $sql .= " WHERE elementtype = '".$this->db->escape($elementtype)."'";
1594 $sql .= " AND name = '".$this->db->escape($attrname)."'";
1595
1596 $resql = $this->db->query($sql);
1597 if ($resql) {
1598 if ($this->db->num_rows($resql)) {
1599 $tab = $this->db->fetch_object($resql);
1600 $id = (int) $tab->id;
1601 } else {
1602 $id = (int) -1;
1603 }
1604 } else {
1605 $id = (int) -2;
1606 }
1607
1608 return $id;
1609 }
1610
1631 public function getListOfTowns($sortfield = "zip,town", $sortorder = 'ASC', $limit = 100, $page = 0, $zipcode = '', $town = '', $active = 1, $sqlfilters = '')
1632 {
1633 $list = array();
1634
1635 $sql = "SELECT rowid AS id, zip, town, fk_county, fk_pays AS fk_country";
1636 $sql .= " FROM ".MAIN_DB_PREFIX."c_ziptown as t";
1637 $sql .= " WHERE t.active = ".((int) $active);
1638 if ($zipcode) {
1639 $sql .= " AND t.zip LIKE '%".$this->db->escape($zipcode)."%'";
1640 }
1641 if ($town) {
1642 $sql .= " AND t.town LIKE '%".$this->db->escape($town)."%'";
1643 }
1644 // Add sql filters
1645 if ($sqlfilters) {
1646 $errormessage = '';
1647 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1648 if ($errormessage) {
1649 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1650 }
1651 }
1652
1653
1654 $sql .= $this->db->order($sortfield, $sortorder);
1655
1656 if ($limit) {
1657 if ($page < 0) {
1658 $page = 0;
1659 }
1660 $offset = $limit * $page;
1661
1662 $sql .= $this->db->plimit($limit, $offset);
1663 }
1664
1665 $result = $this->db->query($sql);
1666
1667 if ($result) {
1668 $num = $this->db->num_rows($result);
1669 $min = min($num, ($limit <= 0 ? $num : $limit));
1670 for ($i = 0; $i < $min; $i++) {
1671 $list[] = $this->db->fetch_object($result);
1672 }
1673 } else {
1674 throw new RestException(503, 'Error when retrieving list of towns : '.$this->db->lasterror());
1675 }
1676
1677 return $list;
1678 }
1679
1700 public function getPaymentTerms($sortfield = "sortorder", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1701 {
1702 $list = array();
1703
1704 if (!DolibarrApiAccess::$user->hasRight('propal', 'lire') && !DolibarrApiAccess::$user->hasRight('commande', 'lire') && !DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
1705 throw new RestException(403);
1706 }
1707
1708 $sql = "SELECT rowid as id, code, sortorder, libelle as label, libelle_facture as descr, type_cdr, nbjour, decalage, module";
1709 $sql .= " FROM ".MAIN_DB_PREFIX."c_payment_term as t";
1710 $sql .= " WHERE t.entity IN (".getEntity('c_payment_term').")";
1711 $sql .= " AND t.active = ".((int) $active);
1712 // Add sql filters
1713 if ($sqlfilters) {
1714 $errormessage = '';
1715 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1716 if ($errormessage) {
1717 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1718 }
1719 }
1720
1721
1722 $sql .= $this->db->order($sortfield, $sortorder);
1723
1724 if ($limit) {
1725 if ($page < 0) {
1726 $page = 0;
1727 }
1728 $offset = $limit * $page;
1729
1730 $sql .= $this->db->plimit($limit, $offset);
1731 }
1732
1733 $result = $this->db->query($sql);
1734
1735 if ($result) {
1736 $num = $this->db->num_rows($result);
1737 $min = min($num, ($limit <= 0 ? $num : $limit));
1738 for ($i = 0; $i < $min; $i++) {
1739 $list[] = $this->db->fetch_object($result);
1740 }
1741 } else {
1742 throw new RestException(503, $this->db->lasterror());
1743 }
1744
1745 return $list;
1746 }
1747
1766 public function getShippingModes($limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
1767 {
1768 $list = array();
1769
1770 $sql = "SELECT rowid as id, code, libelle as label, description, tracking, module";
1771 $sql .= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as t";
1772 $sql .= " WHERE t.entity IN (".getEntity('c_shipment_mode').")";
1773 $sql .= " AND t.active = ".((int) $active);
1774 // Add sql filters
1775 if ($sqlfilters) {
1776 $errormessage = '';
1777 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1778 if ($errormessage) {
1779 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1780 }
1781 }
1782
1783
1784 //$sql.= $this->db->order($sortfield, $sortorder);
1785
1786 if ($limit) {
1787 if ($page < 0) {
1788 $page = 0;
1789 }
1790 $offset = $limit * $page;
1791
1792 $sql .= $this->db->plimit($limit, $offset);
1793 }
1794
1795 $result = $this->db->query($sql);
1796
1797 if ($result) {
1798 $num = $this->db->num_rows($result);
1799 $min = min($num, ($limit <= 0 ? $num : $limit));
1800 for ($i = 0; $i < $min; $i++) {
1801 $method = $this->db->fetch_object($result);
1802 $this->translateLabel($method, $lang, '', array('dict'));
1803 $list[] = $method;
1804 }
1805 } else {
1806 throw new RestException(503, $this->db->lasterror());
1807 }
1808
1809 return $list;
1810 }
1811
1830 public function getListOfMeasuringUnits($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1831 {
1832 $list = array();
1833
1834 $sql = "SELECT t.rowid, t.code, t.label,t.short_label, t.active, t.scale, t.unit_type";
1835 $sql .= " FROM ".MAIN_DB_PREFIX."c_units as t";
1836 $sql .= " WHERE t.active = ".((int) $active);
1837 // Add sql filters
1838 if ($sqlfilters) {
1839 $errormessage = '';
1840 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1841 if ($errormessage) {
1842 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1843 }
1844 }
1845
1846
1847 $sql .= $this->db->order($sortfield, $sortorder);
1848
1849 if ($limit) {
1850 if ($page < 0) {
1851 $page = 0;
1852 }
1853 $offset = $limit * $page;
1854
1855 $sql .= $this->db->plimit($limit, $offset);
1856 }
1857
1858 $result = $this->db->query($sql);
1859
1860 if ($result) {
1861 $num = $this->db->num_rows($result);
1862 $min = min($num, ($limit <= 0 ? $num : $limit));
1863 for ($i = 0; $i < $min; $i++) {
1864 $list[] = $this->db->fetch_object($result);
1865 }
1866 } else {
1867 throw new RestException(503, 'Error when retrieving list of measuring units: '.$this->db->lasterror());
1868 }
1869
1870 return $list;
1871 }
1872
1892 public function getListOfLegalForm($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $active = 1, $sqlfilters = '')
1893 {
1894 $list = array();
1895
1896 $sql = "SELECT t.rowid, t.code, t.fk_pays, t.libelle, t.isvatexempted, t.active, t.module, t.position";
1897 $sql .= " FROM ".MAIN_DB_PREFIX."c_forme_juridique as t";
1898 $sql .= " WHERE t.active = ".((int) $active);
1899 if ($country) {
1900 $sql .= " AND t.fk_pays = ".((int) $country);
1901 }
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 legal form: '.$this->db->lasterror());
1933 }
1934
1935 return $list;
1936 }
1937
1956 public function getListOfStaff($sortfield = "id", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1957 {
1958 $list = array();
1959
1960 $sql = "SELECT t.id, t.code, t.libelle, t.active, t.module";
1961 $sql .= " FROM ".MAIN_DB_PREFIX."c_effectif as t";
1962 $sql .= " WHERE t.active = ".((int) $active);
1963 // Add sql filters
1964 if ($sqlfilters) {
1965 $errormessage = '';
1966 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1967 if ($errormessage) {
1968 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1969 }
1970 }
1971
1972
1973 $sql .= $this->db->order($sortfield, $sortorder);
1974
1975 if ($limit) {
1976 if ($page < 0) {
1977 $page = 0;
1978 }
1979 $offset = $limit * $page;
1980
1981 $sql .= $this->db->plimit($limit, $offset);
1982 }
1983
1984 $result = $this->db->query($sql);
1985
1986 if ($result) {
1987 $num = $this->db->num_rows($result);
1988 $min = min($num, ($limit <= 0 ? $num : $limit));
1989 for ($i = 0; $i < $min; $i++) {
1990 $list[] = $this->db->fetch_object($result);
1991 }
1992 } else {
1993 throw new RestException(503, 'Error when retrieving list of staff: '.$this->db->lasterror());
1994 }
1995
1996 return $list;
1997 }
1998
2017 public function getListOfsocialNetworks($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
2018 {
2019 global $conf;
2020
2021 if (!isModEnabled('socialnetworks')) {
2022 throw new RestException(400, 'API not available: this dictionary is not enabled by setup');
2023 }
2024
2025 $list = array();
2026 //TODO link with multicurrency module
2027 $sql = "SELECT t.rowid, t.entity, t.code, t.label, t.url, t.icon, t.active";
2028 $sql .= " FROM ".MAIN_DB_PREFIX."c_socialnetworks as t";
2029 $sql .= " WHERE t.entity IN (".getEntity('c_socialnetworks').")";
2030 $sql .= " AND t.active = ".((int) $active);
2031 // Add sql filters
2032 if ($sqlfilters) {
2033 $errormessage = '';
2034 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
2035 if ($errormessage) {
2036 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
2037 }
2038 }
2039
2040
2041 $sql .= $this->db->order($sortfield, $sortorder);
2042
2043 if ($limit) {
2044 if ($page < 0) {
2045 $page = 0;
2046 }
2047 $offset = $limit * $page;
2048
2049 $sql .= $this->db->plimit($limit, $offset);
2050 }
2051
2052 $result = $this->db->query($sql);
2053
2054 if ($result) {
2055 $num = $this->db->num_rows($result);
2056 $min = min($num, ($limit <= 0 ? $num : $limit));
2057 for ($i = 0; $i < $min; $i++) {
2058 $list[] = $this->db->fetch_object($result);
2059 }
2060 } else {
2061 throw new RestException(503, 'Error when retrieving list of social networks: '.$this->db->lasterror());
2062 }
2063
2064 return $list;
2065 }
2066
2086 public function getTicketsCategories($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
2087 {
2088 $list = array();
2089
2090 $sql = "SELECT rowid, code, pos, label, use_default, description";
2091 $sql .= " FROM ".MAIN_DB_PREFIX."c_ticket_category as t";
2092 $sql .= " WHERE t.entity IN (".getEntity('c_ticket_category').")";
2093 $sql .= " AND t.active = ".((int) $active);
2094 // Add sql filters
2095 if ($sqlfilters) {
2096 $errormessage = '';
2097 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
2098 if ($errormessage) {
2099 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
2100 }
2101 }
2102
2103
2104 $sql .= $this->db->order($sortfield, $sortorder);
2105
2106 if ($limit) {
2107 if ($page < 0) {
2108 $page = 0;
2109 }
2110 $offset = $limit * $page;
2111
2112 $sql .= $this->db->plimit($limit, $offset);
2113 }
2114
2115 $result = $this->db->query($sql);
2116
2117 if ($result) {
2118 $num = $this->db->num_rows($result);
2119 $min = min($num, ($limit <= 0 ? $num : $limit));
2120 for ($i = 0; $i < $min; $i++) {
2121 $category = $this->db->fetch_object($result);
2122 $this->translateLabel($category, $lang, 'TicketCategoryShort', array('ticket'));
2123 $list[] = $category;
2124 }
2125 } else {
2126 throw new RestException(503, 'Error when retrieving list of ticket categories : '.$this->db->lasterror());
2127 }
2128
2129 return $list;
2130 }
2131
2151 public function getTicketsSeverities($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
2152 {
2153 $list = array();
2154
2155 $sql = "SELECT rowid, code, pos, label, use_default, color, description";
2156 $sql .= " FROM ".MAIN_DB_PREFIX."c_ticket_severity as t";
2157 $sql .= " WHERE t.entity IN (".getEntity('c_ticket_severity').")";
2158 $sql .= " AND t.active = ".((int) $active);
2159 // Add sql filters
2160 if ($sqlfilters) {
2161 $errormessage = '';
2162 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
2163 if ($errormessage) {
2164 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
2165 }
2166 }
2167
2168
2169 $sql .= $this->db->order($sortfield, $sortorder);
2170
2171 if ($limit) {
2172 if ($page < 0) {
2173 $page = 0;
2174 }
2175 $offset = $limit * $page;
2176
2177 $sql .= $this->db->plimit($limit, $offset);
2178 }
2179
2180 $result = $this->db->query($sql);
2181
2182 if ($result) {
2183 $num = $this->db->num_rows($result);
2184 $min = min($num, ($limit <= 0 ? $num : $limit));
2185 for ($i = 0; $i < $min; $i++) {
2186 $severity = $this->db->fetch_object($result);
2187 $this->translateLabel($severity, $lang, 'TicketSeverityShort', array('ticket'));
2188 $list[] = $severity;
2189 }
2190 } else {
2191 throw new RestException(503, 'Error when retrieving list of ticket severities : '.$this->db->lasterror());
2192 }
2193
2194 return $list;
2195 }
2196
2216 public function getTicketsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
2217 {
2218 $list = array();
2219
2220 $sql = "SELECT rowid, code, pos, label, use_default, description";
2221 $sql .= " FROM ".MAIN_DB_PREFIX."c_ticket_type as t";
2222 $sql .= " WHERE t.entity IN (".getEntity('c_ticket_type').")";
2223 $sql .= " AND t.active = ".((int) $active);
2224
2225 // Add sql filters
2226 if ($sqlfilters) {
2227 $errormessage = '';
2228 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
2229 if ($errormessage) {
2230 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
2231 }
2232 }
2233
2234
2235 $sql .= $this->db->order($sortfield, $sortorder);
2236
2237 if ($limit) {
2238 if ($page < 0) {
2239 $page = 0;
2240 }
2241 $offset = $limit * $page;
2242
2243 $sql .= $this->db->plimit($limit, $offset);
2244 }
2245
2246 $result = $this->db->query($sql);
2247
2248 if ($result) {
2249 $num = $this->db->num_rows($result);
2250 $min = min($num, ($limit <= 0 ? $num : $limit));
2251 for ($i = 0; $i < $min; $i++) {
2252 $type = $this->db->fetch_object($result);
2253 $this->translateLabel($type, $lang, 'TicketTypeShort', array('ticket'));
2254 $list[] = $type;
2255 }
2256 } else {
2257 throw new RestException(503, 'Error when retrieving list of ticket types : '.$this->db->lasterror());
2258 }
2259
2260 return $list;
2261 }
2262
2281 public function getListOfIncoterms($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
2282 {
2283 $list = array();
2284
2285 $sql = "SELECT rowid, code, active";
2286 $sql .= " FROM ".MAIN_DB_PREFIX."c_incoterms as t";
2287 $sql .= " WHERE 1=1";
2288
2289 // Add sql filters
2290 if ($sqlfilters) {
2291 $errormessage = '';
2292 if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
2293 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
2294 }
2295 $regexstring = '\‍(([^:\'\‍(\‍)]+:[^:\'\‍(\‍)]+:[^\‍(\‍)]+)\‍)';
2296 $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
2297 }
2298
2299
2300 $sql .= $this->db->order($sortfield, $sortorder);
2301
2302 if ($limit) {
2303 if ($page < 0) {
2304 $page = 0;
2305 }
2306 $offset = $limit * $page;
2307
2308 $sql .= $this->db->plimit($limit, $offset);
2309 }
2310
2311 $result = $this->db->query($sql);
2312
2313 if ($result) {
2314 $num = $this->db->num_rows($result);
2315 $min = min($num, ($limit <= 0 ? $num : $limit));
2316 for ($i = 0; $i < $min; $i++) {
2317 $type = $this->db->fetch_object($result);
2318 $list[] = $type;
2319 }
2320 } else {
2321 throw new RestException(503, 'Error when retrieving list of incoterm types : '.$this->db->lasterror());
2322 }
2323
2324 return $list;
2325 }
2326
2338 public function getCompany()
2339 {
2340 global $conf, $mysoc;
2341
2342 if (!DolibarrApiAccess::$user->admin
2343 && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_COMPANY') || DolibarrApiAccess::$user->login != getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_COMPANY'))) {
2344 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');
2345 }
2346
2347 unset($mysoc->pays);
2348 unset($mysoc->note);
2349 unset($mysoc->nom);
2350
2351 unset($mysoc->lines);
2352
2353 unset($mysoc->effectif);
2354 unset($mysoc->effectif_id);
2355 unset($mysoc->forme_juridique_code);
2356 unset($mysoc->forme_juridique);
2357 unset($mysoc->mode_reglement_supplier_id);
2358 unset($mysoc->cond_reglement_supplier_id);
2359 unset($mysoc->transport_mode_supplier_id);
2360 unset($mysoc->fk_prospectlevel);
2361
2362 unset($mysoc->total_ht);
2363 unset($mysoc->total_tva);
2364 unset($mysoc->total_localtax1);
2365 unset($mysoc->total_localtax2);
2366 unset($mysoc->total_ttc);
2367
2368 unset($mysoc->lastname);
2369 unset($mysoc->firstname);
2370 unset($mysoc->civility_id);
2371
2372 unset($mysoc->client);
2373 unset($mysoc->prospect);
2374 unset($mysoc->fournisseur);
2375 unset($mysoc->contact_id);
2376
2377 unset($mysoc->fk_incoterms);
2378 unset($mysoc->label_incoterms);
2379 unset($mysoc->location_incoterms);
2380
2381 return $this->_cleanObjectDatas($mysoc);
2382 }
2383
2395 public function getEstablishments()
2396 {
2397 $list = array();
2398
2399 $limit = 0;
2400
2401 $sql = "SELECT e.rowid, e.rowid as ref, e.label, e.address, e.zip, e.town, e.status";
2402 $sql .= " FROM ".MAIN_DB_PREFIX."establishment as e";
2403 $sql .= " WHERE e.entity IN (".getEntity('establishment').')';
2404 // if ($type) $sql .= " AND t.type LIKE '%".$this->db->escape($type)."%'";
2405 // if ($module) $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
2406 // Add sql filters
2407
2408 $result = $this->db->query($sql);
2409
2410 if ($result) {
2411 $num = $this->db->num_rows($result);
2412 $min = min($num, ($limit <= 0 ? $num : $limit));
2413 for ($i = 0; $i < $min; $i++) {
2414 $list[] = $this->db->fetch_object($result);
2415 }
2416 } else {
2417 throw new RestException(503, 'Error when retrieving list of establishments : '.$this->db->lasterror());
2418 }
2419
2420 return $list;
2421 }
2422
2434 public function getEtablishmentByID($id)
2435 {
2436 $establishment = new Establishment($this->db);
2437
2438 $result = $establishment->fetch($id);
2439 if ($result < 0) {
2440 throw new RestException(503, 'Error when retrieving establishment : '.$establishment->error);
2441 } elseif ($result == 0) {
2442 throw new RestException(404, 'Establishment not found');
2443 }
2444
2445 return $this->_cleanObjectDatas($establishment);
2446 }
2447
2461 public function getConf($constantname)
2462 {
2463 global $conf;
2464
2465 if (!DolibarrApiAccess::$user->admin
2466 && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_CONST_READ') || DolibarrApiAccess::$user->login != getDolGlobalString('API_LOGINS_ALLOWED_FOR_CONST_READ'))) {
2467 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');
2468 }
2469
2470 if (!preg_match('/^[a-zA-Z0-9_]+$/', $constantname) || !isset($conf->global->$constantname)) {
2471 throw new RestException(400, 'Error Bad or unknown value for constantname');
2472 }
2473 if (isASecretKey($constantname)) {
2474 throw new RestException(403, 'Forbidden. This parameter can not be read with APIs');
2475 }
2476
2477 return getDolGlobalString($constantname);
2478 }
2479
2494 public function getConfs()
2495 {
2496 global $conf;
2497 $list = array();
2498
2499 if (!DolibarrApiAccess::$user->admin
2500 && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_CONST_READ') || DolibarrApiAccess::$user->login != getDolGlobalString('API_LOGINS_ALLOWED_FOR_CONST_READ'))) {
2501 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');
2502 }
2503
2504 $sql = "select name, value";
2505 $sql .= " FROM ".MAIN_DB_PREFIX."const";
2506 $sql .= " WHERE entity IN (".getEntity('const').')';
2507
2508 $result = $this->db->query($sql);
2509
2510 if ($result) {
2511 $num = $this->db->num_rows($result);
2512 for ($i = 0; $i < $num; $i++) {
2513 $obj = $this->db->fetch_object($result);
2514 if (!isASecretKey($obj->name)) {
2515 // We do not return secret keys
2516 $list[$obj->name] = $obj->value;
2517 }
2518 }
2519 } else {
2520 throw new RestException(503, 'Error when retrieving list of const : '.$this->db->lasterror());
2521 }
2522
2523 return $list;
2524 }
2525
2540 public function getCheckIntegrity($target)
2541 {
2542 global $langs, $conf;
2543
2544 if (!DolibarrApiAccess::$user->admin
2545 && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_INTEGRITY_CHECK') || DolibarrApiAccess::$user->login != getDolGlobalString('API_LOGINS_ALLOWED_FOR_INTEGRITY_CHECK'))) {
2546 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');
2547 }
2548
2549 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
2550 require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
2551
2552 $langs->load("admin");
2553
2554 $outexpectedchecksum = '';
2555 $outcurrentchecksum = '';
2556
2557 // Modified or missing files
2558 $file_list = array('missing' => array(), 'updated' => array());
2559
2560 // Local file to compare to
2561 $xmlshortfile = dol_sanitizeFileName('filelist-'.DOL_VERSION.getDolGlobalString('MAIN_FILECHECK_LOCAL_SUFFIX').'.xml'.getDolGlobalString('MAIN_FILECHECK_LOCAL_EXT'));
2562
2563 $xmlfile = DOL_DOCUMENT_ROOT.'/install/'.$xmlshortfile;
2564 if (!preg_match('/\.zip$/i', $xmlfile) && dol_is_file($xmlfile.'.zip')) {
2565 $xmlfile .= '.zip';
2566 }
2567
2568 // Remote file to compare to
2569 $xmlremote = (($target == 'default' || $target == 'local') ? '' : $target);
2570 if (empty($xmlremote) && getDolGlobalString('MAIN_FILECHECK_URL')) {
2571 $xmlremote = getDolGlobalString('MAIN_FILECHECK_URL');
2572 }
2573 $param = 'MAIN_FILECHECK_URL_'.DOL_VERSION;
2574 if (empty($xmlremote) && getDolGlobalString($param)) {
2575 $xmlremote = getDolGlobalString($param);
2576 }
2577 if (empty($xmlremote)) {
2578 $xmlremote = 'https://www.dolibarr.org/files/stable/signatures/filelist-'.DOL_VERSION.'.xml';
2579 }
2580 if ($xmlremote && !preg_match('/^https?:\/\//i', $xmlremote)) {
2581 $langs->load("errors");
2582 throw new RestException(500, $langs->trans("ErrorURLMustStartWithHttp", $xmlremote));
2583 }
2584 if ($xmlremote && !preg_match('/\.xml$/', $xmlremote)) {
2585 $langs->load("errors");
2586 throw new RestException(500, $langs->trans("ErrorURLMustEndWith", $xmlremote, '.xml'));
2587 }
2588
2589 if (LIBXML_VERSION < 20900) {
2590 // Avoid load of external entities (security problem).
2591 // Required only if LIBXML_VERSION < 20900
2592 // @phan-suppress-next-line PhanDeprecatedFunctionInternal
2593 libxml_disable_entity_loader(true);
2594 }
2595
2596 if ($target == 'local') {
2597 if (dol_is_file($xmlfile)) {
2598 $xml = simplexml_load_file($xmlfile);
2599 } else {
2600 throw new RestException(500, $langs->trans('XmlNotFound').': /install/'.$xmlshortfile);
2601 }
2602 } else {
2603 $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.
2604
2605 // Return array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...)
2606 if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != 400 && $xmlarray['http_code'] != 404) {
2607 $xmlfile = $xmlarray['content'];
2608 //print "xmlfilestart".$xmlfile."endxmlfile";
2609 $xml = simplexml_load_string($xmlfile, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NONET);
2610 } else {
2611 $errormsg = $langs->trans('XmlNotFound').': '.$xmlremote.' - '.$xmlarray['http_code'].(($xmlarray['http_code'] == 400 && $xmlarray['content']) ? ' '.$xmlarray['content'] : '').' '.$xmlarray['curl_error_no'].' '.$xmlarray['curl_error_msg'];
2612 throw new RestException(500, $errormsg);
2613 }
2614 }
2615
2616 if ($xml) {
2617 $checksumconcat = array();
2618 $file_list = array();
2619 $out = '';
2620
2621 // Forced constants
2622 if (is_object($xml->dolibarr_constants[0])) {
2623 $out .= load_fiche_titre($langs->trans("ForcedConstants"));
2624
2625 $out .= '<div class="div-table-responsive-no-min">';
2626 $out .= '<table class="noborder">';
2627 $out .= '<tr class="liste_titre">';
2628 $out .= '<td>#</td>';
2629 $out .= '<td>'.$langs->trans("Constant").'</td>';
2630 $out .= '<td class="center">'.$langs->trans("ExpectedValue").'</td>';
2631 $out .= '<td class="center">'.$langs->trans("Value").'</td>';
2632 $out .= '</tr>'."\n";
2633
2634 $i = 0;
2635 foreach ($xml->dolibarr_constants[0]->constant as $constant) { // $constant is a simpleXMLElement
2636 $constname = $constant['name'];
2637 $constvalue = (string) $constant;
2638 $constvalue = (empty($constvalue) ? '0' : $constvalue);
2639 // Value found
2640 $value = '';
2641 if ($constname && getDolGlobalString($constname) != '') {
2642 $value = getDolGlobalString($constname);
2643 }
2644 $valueforchecksum = (empty($value) ? '0' : $value);
2645
2646 $checksumconcat[] = $valueforchecksum;
2647
2648 $i++;
2649 $out .= '<tr class="oddeven">';
2650 $out .= '<td>'.$i.'</td>'."\n";
2651 $out .= '<td>'.dol_escape_htmltag($constname).'</td>'."\n";
2652 $out .= '<td class="center">'.dol_escape_htmltag($constvalue).'</td>'."\n";
2653 $out .= '<td class="center">'.dol_escape_htmltag($valueforchecksum).'</td>'."\n";
2654 $out .= "</tr>\n";
2655 }
2656
2657 if ($i == 0) {
2658 $out .= '<tr class="oddeven"><td colspan="4" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
2659 }
2660 $out .= '</table>';
2661 $out .= '</div>';
2662
2663 $out .= '<br>';
2664 }
2665
2666 // Scan htdocs
2667 if (is_object($xml->dolibarr_htdocs_dir[0])) {
2668 $includecustom = (empty($xml->dolibarr_htdocs_dir[0]['includecustom']) ? 0 : $xml->dolibarr_htdocs_dir[0]['includecustom']);
2669
2670 // Define qualified files (must be same than into generate_filelist_xml.php and in api_setup.class.php)
2671 $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)$';
2672 $regextoexclude = '('.($includecustom ? '' : 'custom|').'documents|escpos-php\/doc|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
2673 $scanfiles = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude);
2674
2675 // Fill file_list with files in signature, new files, modified files
2676 $ret = getFilesUpdated($file_list, $xml->dolibarr_htdocs_dir[0], '', DOL_DOCUMENT_ROOT, $checksumconcat); // Fill array $file_list
2677 '@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';
2678 // Complete with list of new files
2679 foreach ($scanfiles as $keyfile => $valfile) {
2680 $tmprelativefilename = preg_replace('/^'.preg_quote(DOL_DOCUMENT_ROOT, '/').'/', '', $valfile['fullname']);
2681 if (!in_array($tmprelativefilename, $file_list['insignature'])) {
2682 $md5newfile = @md5_file($valfile['fullname']); // Can fails if we don't have permission to open/read file
2683 $file_list['added'][] = array('filename' => $tmprelativefilename, 'md5' => $md5newfile);
2684 }
2685 }
2686
2687 // Files missing
2688 $out .= load_fiche_titre($langs->trans("FilesMissing"));
2689
2690 $out .= '<div class="div-table-responsive-no-min">';
2691 $out .= '<table class="noborder">';
2692 $out .= '<tr class="liste_titre">';
2693 $out .= '<td>#</td>';
2694 $out .= '<td>'.$langs->trans("Filename").'</td>';
2695 $out .= '<td class="center">'.$langs->trans("ExpectedChecksum").'</td>';
2696 $out .= '</tr>'."\n";
2697 $tmpfilelist = dol_sort_array($file_list['missing'], 'filename');
2698 if (is_array($tmpfilelist) && count($tmpfilelist)) {
2699 $i = 0;
2700 foreach ($tmpfilelist as $file) {
2701 $i++;
2702 $out .= '<tr class="oddeven">';
2703 $out .= '<td>'.$i.'</td>'."\n";
2704 $out .= '<td>'.dol_escape_htmltag($file['filename']).'</td>'."\n";
2705 $out .= '<td class="center">'.(array_key_exists('expectedmd5', $file) ? $file['expectedmd5'] : '').'</td>'."\n";
2706 $out .= "</tr>\n";
2707 }
2708 } else {
2709 $out .= '<tr class="oddeven"><td colspan="3" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
2710 }
2711 $out .= '</table>';
2712 $out .= '</div>';
2713
2714 $out .= '<br>';
2715
2716 // Files modified
2717 $out .= load_fiche_titre($langs->trans("FilesModified"));
2718
2719 $totalsize = 0;
2720 $out .= '<div class="div-table-responsive-no-min">';
2721 $out .= '<table class="noborder">';
2722 $out .= '<tr class="liste_titre">';
2723 $out .= '<td>#</td>';
2724 $out .= '<td>'.$langs->trans("Filename").'</td>';
2725 $out .= '<td class="center">'.$langs->trans("ExpectedChecksum").'</td>';
2726 $out .= '<td class="center">'.$langs->trans("CurrentChecksum").'</td>';
2727 $out .= '<td class="right">'.$langs->trans("Size").'</td>';
2728 $out .= '<td class="right">'.$langs->trans("DateModification").'</td>';
2729 $out .= '</tr>'."\n";
2730 $tmpfilelist2 = dol_sort_array($file_list['updated'], 'filename');
2731 if (is_array($tmpfilelist2) && count($tmpfilelist2)) {
2732 $i = 0;
2733 foreach ($tmpfilelist2 as $file) {
2734 $i++;
2735 $out .= '<tr class="oddeven">';
2736 $out .= '<td>'.$i.'</td>'."\n";
2737 $out .= '<td>'.dol_escape_htmltag($file['filename']).'</td>'."\n";
2738 $out .= '<td class="center">'.$file['expectedmd5'].'</td>'."\n";
2739 $out .= '<td class="center">'.$file['md5'].'</td>'."\n";
2740 $size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']);
2741 $totalsize += $size;
2742 $out .= '<td class="right">'.dol_print_size($size).'</td>'."\n";
2743 $out .= '<td class="right">'.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']), 'dayhour').'</td>'."\n";
2744 $out .= "</tr>\n";
2745 }
2746 $out .= '<tr class="liste_total">';
2747 $out .= '<td></td>'."\n";
2748 $out .= '<td>'.$langs->trans("Total").'</td>'."\n";
2749 $out .= '<td align="center"></td>'."\n";
2750 $out .= '<td align="center"></td>'."\n";
2751 $out .= '<td class="right">'.dol_print_size($totalsize).'</td>'."\n";
2752 $out .= '<td class="right"></td>'."\n";
2753 $out .= "</tr>\n";
2754 } else {
2755 $out .= '<tr class="oddeven"><td colspan="5" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
2756 }
2757 $out .= '</table>';
2758 $out .= '</div>';
2759
2760 $out .= '<br>';
2761
2762 // Files added
2763 $out .= load_fiche_titre($langs->trans("FilesAdded"));
2764
2765 $totalsize = 0;
2766 $out .= '<div class="div-table-responsive-no-min">';
2767 $out .= '<table class="noborder">';
2768 $out .= '<tr class="liste_titre">';
2769 $out .= '<td>#</td>';
2770 $out .= '<td>'.$langs->trans("Filename").'</td>';
2771 $out .= '<td class="center">'.$langs->trans("ExpectedChecksum").'</td>';
2772 $out .= '<td class="center">'.$langs->trans("CurrentChecksum").'</td>';
2773 $out .= '<td class="right">'.$langs->trans("Size").'</td>';
2774 $out .= '<td class="right">'.$langs->trans("DateModification").'</td>';
2775 $out .= '</tr>'."\n";
2776 $tmpfilelist3 = dol_sort_array($file_list['added'], 'filename');
2777 if (is_array($tmpfilelist3) && count($tmpfilelist3)) {
2778 $i = 0;
2779 foreach ($tmpfilelist3 as $file) {
2780 $i++;
2781 $out .= '<tr class="oddeven">';
2782 $out .= '<td>'.$i.'</td>'."\n";
2783 $out .= '<td>'.dol_escape_htmltag($file['filename']).'</td>'."\n";
2784 $out .= '<td class="center">'.$file['expectedmd5'].'</td>'."\n"; // @phan-suppress-current-line PhanTypeInvalidDimOffset,PhanTypeSuspiciousStringExpression
2785 $out .= '<td class="center">'.$file['md5'].'</td>'."\n";
2786 $size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']);
2787 $totalsize += $size;
2788 $out .= '<td class="right">'.dol_print_size($size).'</td>'."\n";
2789 $out .= '<td class="right">'.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']), 'dayhour').'</td>'."\n";
2790 $out .= "</tr>\n";
2791 }
2792 $out .= '<tr class="liste_total">';
2793 $out .= '<td></td>'."\n";
2794 $out .= '<td>'.$langs->trans("Total").'</td>'."\n";
2795 $out .= '<td align="center"></td>'."\n";
2796 $out .= '<td align="center"></td>'."\n";
2797 $out .= '<td class="right">'.dol_print_size($totalsize).'</td>'."\n";
2798 $out .= '<td class="right"></td>'."\n";
2799 $out .= "</tr>\n";
2800 } else {
2801 $out .= '<tr class="oddeven"><td colspan="5" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
2802 }
2803 $out .= '</table>';
2804 $out .= '</div>';
2805
2806
2807 // Show warning
2808 if (empty($tmpfilelist) && empty($tmpfilelist2) && empty($tmpfilelist3)) {
2809 //setEventMessages($langs->trans("FileIntegrityIsStrictlyConformedWithReference"), null, 'mesgs');
2810 } else {
2811 //setEventMessages($langs->trans("FileIntegritySomeFilesWereRemovedOrModified"), null, 'warnings');
2812 }
2813 } else {
2814 throw new RestException(500, 'Error: Failed to found dolibarr_htdocs_dir into XML file '.$xmlfile);
2815 }
2816
2817
2818 // Scan scripts
2819 asort($checksumconcat); // Sort list of checksum
2820 $checksumget = md5(implode(',', $checksumconcat));
2821 $checksumtoget = trim((string) $xml->dolibarr_htdocs_dir_checksum);
2822
2823 $outexpectedchecksum = ($checksumtoget ? $checksumtoget : $langs->trans("Unknown"));
2824 if ($checksumget == $checksumtoget) {
2825 if (count($file_list['added'])) {
2826 $resultcode = 'warning';
2827 $resultcomment = 'FileIntegrityIsOkButFilesWereAdded';
2828 //$outcurrentchecksum = $checksumget.' - <span class="'.$resultcode.'">'.$langs->trans("FileIntegrityIsOkButFilesWereAdded").'</span>';
2829 $outcurrentchecksum = $checksumget;
2830 } else {
2831 $resultcode = 'ok';
2832 $resultcomment = 'Success';
2833 //$outcurrentchecksum = '<span class="'.$resultcode.'">'.$checksumget.'</span>';
2834 $outcurrentchecksum = $checksumget;
2835 }
2836 } else {
2837 $resultcode = 'error';
2838 $resultcomment = 'Error';
2839 //$outcurrentchecksum = '<span class="'.$resultcode.'">'.$checksumget.'</span>';
2840 $outcurrentchecksum = $checksumget;
2841 }
2842 } else {
2843 throw new RestException(404, 'No signature file known');
2844 }
2845
2846 return array('resultcode' => $resultcode, 'resultcomment' => $resultcomment, 'expectedchecksum' => $outexpectedchecksum, 'currentchecksum' => $outcurrentchecksum, 'out' => $out);
2847 }
2848
2849
2861 public function getModules()
2862 {
2863 global $conf;
2864
2865 if (!DolibarrApiAccess::$user->admin
2866 && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_MODULES') || DolibarrApiAccess::$user->login != getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_MODULES'))) {
2867 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');
2868 }
2869
2870 sort($conf->modules);
2871
2872 return $this->_cleanObjectDatas($conf->modules);
2873 }
2874}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
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:33
_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:98
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.
getConfs()
Get all setup variables.
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...
jsonOrUnserialize($stringtodecode)
Decode an encode string.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
getURLContent($url, $postorget='GET', $param='', $followlocation=1, $addheaders=array(), $allowedschemes=array('http', 'https'), $localurl=0, $ssl_verifypeer=-1, $timeoutconnect=0, $timeoutresponse=0)
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