dolibarr  20.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-2021 Frédéric France <frederic.france@netlogic.fr>
7  * Copyright (C) 2018-2022 Thibault FOUCART <support@ptibogxiv.net>
8  * Copyright (C) 2024 Jon Bendtsen <jon.bendtsen.github@jonb.dk>
9  *
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
23  */
24 
25 use Luracast\Restler\RestException;
26 
27 require_once DOL_DOCUMENT_ROOT.'/main.inc.php';
28 require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php';
29 require_once DOL_DOCUMENT_ROOT.'/core/class/cstate.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/class/cregion.class.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/hrm/class/establishment.class.php';
33 
40 class Setup extends DolibarrApi
41 {
42  private $translations = null;
43 
47  public function __construct()
48  {
49  global $db;
50  $this->db = $db;
51  }
52 
71  public function getOrderingMethods($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
72  {
73  $list = array();
74 
75  if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) {
76  throw new RestException(403);
77  }
78 
79  $sql = "SELECT rowid, code, libelle as label, module";
80  $sql .= " FROM ".MAIN_DB_PREFIX."c_input_method as t";
81  $sql .= " WHERE t.active = ".((int) $active);
82  // Add sql filters
83  if ($sqlfilters) {
84  $errormessage = '';
85  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
86  if ($errormessage) {
87  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
88  }
89  }
90 
91 
92  $sql .= $this->db->order($sortfield, $sortorder);
93 
94  if ($limit) {
95  if ($page < 0) {
96  $page = 0;
97  }
98  $offset = $limit * $page;
99 
100  $sql .= $this->db->plimit($limit, $offset);
101  }
102 
103  $result = $this->db->query($sql);
104 
105  if ($result) {
106  $num = $this->db->num_rows($result);
107  $min = min($num, ($limit <= 0 ? $num : $limit));
108  for ($i = 0; $i < $min; $i++) {
109  $list[] = $this->db->fetch_object($result);
110  }
111  } else {
112  throw new RestException(503, $this->db->lasterror());
113  }
114 
115  return $list;
116  }
117 
135  public function getOrderingOrigins($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
136  {
137  $list = array();
138 
139  if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) {
140  throw new RestException(403);
141  }
142 
143  $sql = "SELECT rowid, code, label, module";
144  $sql .= " FROM ".MAIN_DB_PREFIX."c_input_reason as t";
145  $sql .= " WHERE t.active = ".((int) $active);
146  // Add sql filters
147  if ($sqlfilters) {
148  $errormessage = '';
149  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
150  if ($errormessage) {
151  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
152  }
153  }
154 
155 
156  $sql .= $this->db->order($sortfield, $sortorder);
157 
158  if ($limit) {
159  if ($page < 0) {
160  $page = 0;
161  }
162  $offset = $limit * $page;
163 
164  $sql .= $this->db->plimit($limit, $offset);
165  }
166 
167  $result = $this->db->query($sql);
168 
169  if ($result) {
170  $num = $this->db->num_rows($result);
171  $min = min($num, ($limit <= 0 ? $num : $limit));
172  for ($i = 0; $i < $min; $i++) {
173  $list[] = $this->db->fetch_object($result);
174  }
175  } else {
176  throw new RestException(503, $this->db->lasterror());
177  }
178 
179  return $list;
180  }
181 
200  public function getPaymentTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
201  {
202  $list = array();
203 
204  if (!DolibarrApiAccess::$user->hasRight('propal', 'lire') && !DolibarrApiAccess::$user->hasRight('commande', 'lire') && !DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
205  throw new RestException(403);
206  }
207 
208  $sql = "SELECT id, code, type, libelle as label, module";
209  $sql .= " FROM ".MAIN_DB_PREFIX."c_paiement as t";
210  $sql .= " WHERE t.entity IN (".getEntity('c_paiement').")";
211  $sql .= " AND t.active = ".((int) $active);
212  // Add sql filters
213  if ($sqlfilters) {
214  $errormessage = '';
215  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
216  if ($errormessage) {
217  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
218  }
219  }
220 
221 
222  $sql .= $this->db->order($sortfield, $sortorder);
223 
224  if ($limit) {
225  if ($page < 0) {
226  $page = 0;
227  }
228  $offset = $limit * $page;
229 
230  $sql .= $this->db->plimit($limit, $offset);
231  }
232 
233  $result = $this->db->query($sql);
234 
235  if ($result) {
236  $num = $this->db->num_rows($result);
237  $min = min($num, ($limit <= 0 ? $num : $limit));
238  for ($i = 0; $i < $min; $i++) {
239  $list[] = $this->db->fetch_object($result);
240  }
241  } else {
242  throw new RestException(503, $this->db->lasterror());
243  }
244 
245  return $list;
246  }
266  public function getListOfRegions($sortfield = "code_region", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $filter = '', $sqlfilters = '')
267  {
268  $list = array();
269 
270  // Note: The filter is not applied in the SQL request because it must
271  // be applied to the translated names, not to the names in database.
272  $sql = "SELECT t.rowid FROM ".MAIN_DB_PREFIX."c_regions as t";
273  $sql .= " WHERE 1 = 1";
274  if ($country) {
275  $sql .= " AND t.fk_pays = ".((int) $country);
276  }
277  // Add sql filters
278  if ($sqlfilters) {
279  $errormessage = '';
280  if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
281  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
282  }
283  $regexstring = '\‍(([^:\'\‍(\‍)]+:[^:\'\‍(\‍)]+:[^\‍(\‍)]+)\‍)';
284  $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
285  }
286 
287  $sql .= $this->db->order($sortfield, $sortorder);
288 
289  if ($limit) {
290  if ($page < 0) {
291  $page = 0;
292  }
293  $offset = $limit * $page;
294 
295  $sql .= $this->db->plimit($limit, $offset);
296  }
297 
298  $result = $this->db->query($sql);
299 
300  if ($result) {
301  $num = $this->db->num_rows($result);
302  $min = min($num, ($limit <= 0 ? $num : $limit));
303  for ($i = 0; $i < $min; $i++) {
304  $obj = $this->db->fetch_object($result);
305  $region = new Cregion($this->db);
306  if ($region->fetch($obj->rowid) > 0) {
307  if (empty($filter) || stripos($region->name, $filter) !== false) {
308  $list[] = $this->_cleanObjectDatas($region);
309  }
310  }
311  }
312  } else {
313  throw new RestException(503, 'Error when retrieving list of regions');
314  }
315 
316  return $list;
317  }
318 
330  public function getRegionByID($id)
331  {
332  return $this->_fetchCregion($id, '');
333  }
334 
346  public function getRegionByCode($code)
347  {
348  return $this->_fetchCregion('', $code);
349  }
350 
373  public function getListOfStates($sortfield = "code_departement", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $filter = '', $sqlfilters = '')
374  {
375  $list = array();
376 
377  // Note: The filter is not applied in the SQL request because it must
378  // be applied to the translated names, not to the names in database.
379  $sql = "SELECT t.rowid FROM ".MAIN_DB_PREFIX."c_departements as t";
380  if ($country) {
381  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_regions as d ON t.fk_region = d.code_region";
382  }
383  $sql .= " WHERE 1 = 1";
384  if ($country) {
385  $sql .= " AND d.fk_pays = ".((int) $country);
386  }
387  // Add sql filters
388  if ($sqlfilters) {
389  $errormessage = '';
390  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
391  if ($errormessage) {
392  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
393  }
394  }
395 
396  $sql .= $this->db->order($sortfield, $sortorder);
397 
398  if ($limit) {
399  if ($page < 0) {
400  $page = 0;
401  }
402  $offset = $limit * $page;
403 
404  $sql .= $this->db->plimit($limit, $offset);
405  }
406 
407  $result = $this->db->query($sql);
408 
409  if ($result) {
410  $num = $this->db->num_rows($result);
411  $min = min($num, ($limit <= 0 ? $num : $limit));
412  for ($i = 0; $i < $min; $i++) {
413  $obj = $this->db->fetch_object($result);
414  $state = new Cstate($this->db);
415  if ($state->fetch($obj->rowid) > 0) {
416  if (empty($filter) || stripos($state->label, $filter) !== false) {
417  $list[] = $this->_cleanObjectDatas($state);
418  }
419  }
420  }
421  } else {
422  throw new RestException(503, 'Error when retrieving list of states');
423  }
424 
425  return $list;
426  }
427 
439  public function getStateByID($id)
440  {
441  return $this->_fetchCstate($id, '');
442  }
443 
455  public function getStateByCode($code)
456  {
457  return $this->_fetchCstate('', $code);
458  }
459 
482  public function getListOfCountries($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $lang = '', $sqlfilters = '')
483  {
484  $list = array();
485 
486  // Note: The filter is not applied in the SQL request because it must
487  // be applied to the translated names, not to the names in database.
488  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_country as t";
489  $sql .= " WHERE 1 = 1";
490  // Add sql filters
491  if ($sqlfilters) {
492  $errormessage = '';
493  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
494  if ($errormessage) {
495  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
496  }
497  }
498 
499  $sql .= $this->db->order($sortfield, $sortorder);
500 
501  if ($limit) {
502  if ($page < 0) {
503  $page = 0;
504  }
505  $offset = $limit * $page;
506 
507  $sql .= $this->db->plimit($limit, $offset);
508  }
509 
510  $result = $this->db->query($sql);
511 
512  if ($result) {
513  $num = $this->db->num_rows($result);
514  $min = min($num, ($limit <= 0 ? $num : $limit));
515  for ($i = 0; $i < $min; $i++) {
516  $obj = $this->db->fetch_object($result);
517  $country = new Ccountry($this->db);
518  if ($country->fetch($obj->rowid) > 0) {
519  // Translate the name of the country if needed
520  // and then apply the filter if there is one.
521  $this->translateLabel($country, $lang, 'Country');
522 
523  if (empty($filter) || stripos($country->label, $filter) !== false) {
524  $list[] = $this->_cleanObjectDatas($country);
525  }
526  }
527  }
528  } else {
529  throw new RestException(503, 'Error when retrieving list of countries');
530  }
531 
532  return $list;
533  }
534 
547  public function getCountryByID($id, $lang = '')
548  {
549  return $this->_fetchCcountry($id, '', '', $lang);
550  }
551 
564  public function getCountryByCode($code, $lang = '')
565  {
566  return $this->_fetchCcountry('', $code, '', $lang);
567  }
568 
581  public function getCountryByISO($iso, $lang = '')
582  {
583  return $this->_fetchCcountry('', '', $iso, $lang);
584  }
585 
595  private function _fetchCregion($id, $code = '')
596  {
597  $region = new Cregion($this->db);
598 
599  $result = $region->fetch($id, $code);
600  if ($result < 0) {
601  throw new RestException(503, 'Error when retrieving region : '.$region->error);
602  } elseif ($result == 0) {
603  throw new RestException(404, 'Region not found');
604  }
605 
606  return $this->_cleanObjectDatas($region);
607  }
608 
618  private function _fetchCstate($id, $code = '')
619  {
620  $state = new Cstate($this->db);
621 
622  $result = $state->fetch($id, $code);
623  if ($result < 0) {
624  throw new RestException(503, 'Error when retrieving state : '.$state->error);
625  } elseif ($result == 0) {
626  throw new RestException(404, 'State not found');
627  }
628 
629  return $this->_cleanObjectDatas($state);
630  }
631 
643  private function _fetchCcountry($id, $code = '', $iso = '', $lang = '')
644  {
645  $country = new Ccountry($this->db);
646 
647  $result = $country->fetch($id, $code, $iso);
648 
649  if ($result < 0) {
650  throw new RestException(503, 'Error when retrieving country : '.$country->error);
651  } elseif ($result == 0) {
652  throw new RestException(404, 'Country not found');
653  }
654 
655  $this->translateLabel($country, $lang, 'Country');
656 
657  return $this->_cleanObjectDatas($country);
658  }
659 
678  public function getAvailability($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
679  {
680  $list = array();
681 
682  if (!DolibarrApiAccess::$user->hasRight('commande', 'lire')) {
683  throw new RestException(403);
684  }
685 
686  $sql = "SELECT rowid, code, label";
687  $sql .= " FROM ".MAIN_DB_PREFIX."c_availability as t";
688  $sql .= " WHERE t.active = ".((int) $active);
689  // Add sql filters
690  if ($sqlfilters) {
691  $errormessage = '';
692  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
693  if ($errormessage) {
694  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
695  }
696  }
697 
698 
699  $sql .= $this->db->order($sortfield, $sortorder);
700 
701  if ($limit) {
702  if ($page < 0) {
703  $page = 0;
704  }
705  $offset = $limit * $page;
706 
707  $sql .= $this->db->plimit($limit, $offset);
708  }
709 
710  $result = $this->db->query($sql);
711 
712  if ($result) {
713  $num = $this->db->num_rows($result);
714  $min = min($num, ($limit <= 0 ? $num : $limit));
715  for ($i = 0; $i < $min; $i++) {
716  $list[] = $this->db->fetch_object($result);
717  }
718  } else {
719  throw new RestException(503, $this->db->lasterror());
720  }
721 
722  return $list;
723  }
724 
725  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
732  protected function _cleanObjectDatas($object)
733  {
734  // phpcs:enable
735  $object = parent::_cleanObjectDatas($object);
736 
737  unset($object->error);
738  unset($object->errors);
739 
740  return $object;
741  }
742 
752  private function translateLabel($object, $lang, $prefix = 'Country', $dict = array('dict'))
753  {
754  if (!empty($lang)) {
755  // Load the translations if this is a new language.
756  if ($this->translations == null || $this->translations->getDefaultLang() !== $lang) {
757  global $conf;
758  $this->translations = new Translate('', $conf);
759  $this->translations->setDefaultLang($lang);
760  $this->translations->loadLangs($dict);
761  }
762  if ($object->code) {
763  $key = $prefix.$object->code;
764 
765  $translation = $this->translations->trans($key);
766  if ($translation != $key) {
767  $object->label = html_entity_decode($translation);
768  }
769  }
770  }
771  }
772 
791  public function getListOfEventTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $active = 1, $sqlfilters = '')
792  {
793  $list = array();
794 
795  $sql = "SELECT id, code, type, libelle as label, module";
796  $sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm as t";
797  $sql .= " WHERE t.active = ".((int) $active);
798  if ($type) {
799  $sql .= " AND t.type LIKE '%".$this->db->escape($type)."%'";
800  }
801  if ($module) {
802  $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
803  }
804  // Add sql filters
805  if ($sqlfilters) {
806  $errormessage = '';
807  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
808  if ($errormessage) {
809  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
810  }
811  }
812 
813 
814  $sql .= $this->db->order($sortfield, $sortorder);
815 
816  if ($limit) {
817  if ($page < 0) {
818  $page = 0;
819  }
820  $offset = $limit * $page;
821 
822  $sql .= $this->db->plimit($limit, $offset);
823  }
824 
825  $result = $this->db->query($sql);
826 
827  if ($result) {
828  $num = $this->db->num_rows($result);
829  $min = min($num, ($limit <= 0 ? $num : $limit));
830  for ($i = 0; $i < $min; $i++) {
831  $list[] = $this->db->fetch_object($result);
832  }
833  } else {
834  throw new RestException(503, 'Error when retrieving list of events types : '.$this->db->lasterror());
835  }
836 
837  return $list;
838  }
839 
840 
858  public function getListOfExpenseReportsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $module = '', $active = 1, $sqlfilters = '')
859  {
860  $list = array();
861 
862  $sql = "SELECT id, code, label, accountancy_code, active, module, position";
863  $sql .= " FROM ".MAIN_DB_PREFIX."c_type_fees as t";
864  $sql .= " WHERE t.active = ".((int) $active);
865  if ($module) {
866  $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
867  }
868  // Add sql filters
869  if ($sqlfilters) {
870  $errormessage = '';
871  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
872  if ($errormessage) {
873  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
874  }
875  }
876 
877 
878  $sql .= $this->db->order($sortfield, $sortorder);
879 
880  if ($limit) {
881  if ($page < 0) {
882  $page = 0;
883  }
884  $offset = $limit * $page;
885 
886  $sql .= $this->db->plimit($limit, $offset);
887  }
888 
889  $result = $this->db->query($sql);
890 
891  if ($result) {
892  $num = $this->db->num_rows($result);
893  $min = min($num, ($limit <= 0 ? $num : $limit));
894  for ($i = 0; $i < $min; $i++) {
895  $list[] = $this->db->fetch_object($result);
896  }
897  } else {
898  throw new RestException(503, 'Error when retrieving list of expense report types : '.$this->db->lasterror());
899  }
900 
901  return $list;
902  }
903 
904 
924  public function getListOfContactTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $active = 1, $lang = '', $sqlfilters = '')
925  {
926  $list = array();
927 
928  $sql = "SELECT rowid, code, element as type, libelle as label, source, module, position";
929  $sql .= " FROM ".MAIN_DB_PREFIX."c_type_contact as t";
930  $sql .= " WHERE t.active = ".((int) $active);
931  if ($type) {
932  $sql .= " AND type LIKE '%".$this->db->escape($type)."%'";
933  }
934  if ($module) {
935  $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
936  }
937  // Add sql filters
938  if ($sqlfilters) {
939  $errormessage = '';
940  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
941  if ($errormessage) {
942  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
943  }
944  }
945 
946 
947  $sql .= $this->db->order($sortfield, $sortorder);
948 
949  if ($limit) {
950  if ($page < 0) {
951  $page = 0;
952  }
953  $offset = $limit * $page;
954 
955  $sql .= $this->db->plimit($limit, $offset);
956  }
957 
958  $result = $this->db->query($sql);
959 
960  if ($result) {
961  $num = $this->db->num_rows($result);
962  $min = min($num, ($limit <= 0 ? $num : $limit));
963  for ($i = 0; $i < $min; $i++) {
964  $contact_type = $this->db->fetch_object($result);
965  $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"));
966  $list[] = $contact_type;
967  }
968  } else {
969  throw new RestException(503, 'Error when retrieving list of contacts types : '.$this->db->lasterror());
970  }
971 
972  return $list;
973  }
974 
993  public function getListOfCivilities($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $module = '', $active = 1, $lang = '', $sqlfilters = '')
994  {
995  $list = array();
996 
997  $sql = "SELECT rowid, code, label, module";
998  $sql .= " FROM ".MAIN_DB_PREFIX."c_civility as t";
999  $sql .= " WHERE t.active = ".((int) $active);
1000  if ($module) {
1001  $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
1002  }
1003  // Add sql filters
1004  if ($sqlfilters) {
1005  $errormessage = '';
1006  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1007  if ($errormessage) {
1008  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1009  }
1010  }
1011 
1012 
1013  $sql .= $this->db->order($sortfield, $sortorder);
1014 
1015  if ($limit) {
1016  if ($page < 0) {
1017  $page = 0;
1018  }
1019  $offset = $limit * $page;
1020 
1021  $sql .= $this->db->plimit($limit, $offset);
1022  }
1023 
1024  $result = $this->db->query($sql);
1025 
1026  if ($result) {
1027  $num = $this->db->num_rows($result);
1028  $min = min($num, ($limit <= 0 ? $num : $limit));
1029  for ($i = 0; $i < $min; $i++) {
1030  $civility = $this->db->fetch_object($result);
1031  $this->translateLabel($civility, $lang, 'Civility', array('dict'));
1032  $list[] = $civility;
1033  }
1034  } else {
1035  throw new RestException(503, 'Error when retrieving list of civility : '.$this->db->lasterror());
1036  }
1037 
1038  return $list;
1039  }
1040 
1058  public function getListOfCurrencies($multicurrency = 0, $sortfield = "code_iso", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1059  {
1060  $list = array();
1061  $sql = "SELECT t.code_iso, t.label, t.unicode";
1062  if (!empty($multicurrency)) {
1063  $sql .= " , cr.date_sync, cr.rate ";
1064  }
1065  $sql .= " FROM ".MAIN_DB_PREFIX."c_currencies as t";
1066  if (!empty($multicurrency)) {
1067  $sql .= " JOIN ".MAIN_DB_PREFIX."multicurrency as m ON m.code=t.code_iso";
1068  $sql .= " JOIN ".MAIN_DB_PREFIX."multicurrency_rate as cr ON (m.rowid = cr.fk_multicurrency)";
1069  }
1070  $sql .= " WHERE t.active = ".((int) $active);
1071  if (!empty($multicurrency)) {
1072  $sql .= " AND m.entity IN (".getEntity('multicurrency').")";
1073  if (!empty($multicurrency) && $multicurrency != 2) {
1074  $sql .= " AND cr.date_sync = (SELECT MAX(cr2.date_sync) FROM ".MAIN_DB_PREFIX."multicurrency_rate AS cr2 WHERE cr2.fk_multicurrency = m.rowid)";
1075  }
1076  }
1077 
1078  // Add sql filters
1079  if ($sqlfilters) {
1080  $errormessage = '';
1081  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1082  if ($errormessage) {
1083  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1084  }
1085  }
1086 
1087 
1088  $sql .= $this->db->order($sortfield, $sortorder);
1089 
1090  if ($limit) {
1091  if ($page < 0) {
1092  $page = 0;
1093  }
1094  $offset = $limit * $page;
1095 
1096  $sql .= $this->db->plimit($limit, $offset);
1097  }
1098 
1099  $result = $this->db->query($sql);
1100 
1101  if ($result) {
1102  $num = $this->db->num_rows($result);
1103  $min = min($num, ($limit <= 0 ? $num : $limit));
1104  for ($i = 0; $i < $min; $i++) {
1105  $list[] = $this->db->fetch_object($result);
1106  }
1107  } else {
1108  throw new RestException(503, 'Error when retrieving list of currency : '.$this->db->lasterror());
1109  }
1110 
1111  return $list;
1112  }
1113 
1128  public function getListOfExtrafields($sortfield = "t.pos", $sortorder = 'ASC', $elementtype = '', $sqlfilters = '')
1129  {
1130  $list = array();
1131 
1132  if (!DolibarrApiAccess::$user->admin) {
1133  throw new RestException(403, 'Only an admin user can get list of extrafields');
1134  }
1135 
1136  if ($elementtype == 'thirdparty') {
1137  $elementtype = 'societe';
1138  }
1139  if ($elementtype == 'contact') {
1140  $elementtype = 'socpeople';
1141  }
1142 
1143  $sql = "SELECT t.rowid as id, t.name, t.entity, t.elementtype, t.label, t.type, t.size, t.fieldcomputed, t.fielddefault,";
1144  $sql .= " t.fieldunique, t.fieldrequired, t.perms, t.enabled, t.pos, t.alwayseditable, t.param, t.list, t.printable,";
1145  $sql .= " t.totalizable, t.langs, t.help, t.css, t.cssview, t.fk_user_author, t.fk_user_modif, t.datec, t.tms";
1146  $sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
1147  $sql .= " WHERE t.entity IN (".getEntity('extrafields').")";
1148  if (!empty($elementtype)) {
1149  $sql .= " AND t.elementtype = '".$this->db->escape($elementtype)."'";
1150  }
1151  // Add sql filters
1152  if ($sqlfilters) {
1153  $errormessage = '';
1154  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1155  if ($errormessage) {
1156  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1157  }
1158  }
1159 
1160  $sql .= $this->db->order($sortfield, $sortorder);
1161 
1162  $resql = $this->db->query($sql);
1163  if ($resql) {
1164  if ($this->db->num_rows($resql)) {
1165  while ($tab = $this->db->fetch_object($resql)) {
1166  // New usage
1167  $list[$tab->elementtype][$tab->name]['id'] = $tab->id;
1168  $list[$tab->elementtype][$tab->name]['type'] = $tab->type;
1169  $list[$tab->elementtype][$tab->name]['label'] = $tab->label;
1170  $list[$tab->elementtype][$tab->name]['size'] = $tab->size;
1171  $list[$tab->elementtype][$tab->name]['elementtype'] = $tab->elementtype;
1172  $list[$tab->elementtype][$tab->name]['default'] = $tab->fielddefault;
1173  $list[$tab->elementtype][$tab->name]['computed'] = $tab->fieldcomputed;
1174  $list[$tab->elementtype][$tab->name]['unique'] = $tab->fieldunique;
1175  $list[$tab->elementtype][$tab->name]['required'] = $tab->fieldrequired;
1176  $list[$tab->elementtype][$tab->name]['param'] = ($tab->param ? jsonOrUnserialize($tab->param) : ''); // This may be a string encoded with serialise() or json_encode()
1177  $list[$tab->elementtype][$tab->name]['pos'] = $tab->pos;
1178  $list[$tab->elementtype][$tab->name]['alwayseditable'] = $tab->alwayseditable;
1179  $list[$tab->elementtype][$tab->name]['perms'] = $tab->perms;
1180  $list[$tab->elementtype][$tab->name]['list'] = $tab->list;
1181  $list[$tab->elementtype][$tab->name]['printable'] = $tab->printable;
1182  $list[$tab->elementtype][$tab->name]['totalizable'] = $tab->totalizable;
1183  $list[$tab->elementtype][$tab->name]['langs'] = $tab->langs;
1184  $list[$tab->elementtype][$tab->name]['help'] = $tab->help;
1185  $list[$tab->elementtype][$tab->name]['css'] = $tab->css;
1186  $list[$tab->elementtype][$tab->name]['cssview'] = $tab->cssview;
1187  $list[$tab->elementtype][$tab->name]['csslist'] = $tab->csslist;
1188  $list[$tab->elementtype][$tab->name]['fk_user_author'] = $tab->fk_user_author;
1189  $list[$tab->elementtype][$tab->name]['fk_user_modif'] = $tab->fk_user_modif;
1190  $list[$tab->elementtype][$tab->name]['datec'] = $tab->datec;
1191  $list[$tab->elementtype][$tab->name]['tms'] = $tab->tms;
1192  }
1193  }
1194  } else {
1195  throw new RestException(503, 'Error when retrieving list of extra fields : '.$this->db->lasterror());
1196  }
1197 
1198  return $list;
1199  }
1200 
1211  public function deleteExtrafieldsFromNames($attrname, $elementtype)
1212  {
1213  if (!DolibarrApiAccess::$user->admin) {
1214  throw new RestException(403, 'Only an admin user can delete an extrafield by attrname and elementtype');
1215  }
1216 
1217  $extrafields = new ExtraFields($this->db);
1218 
1219  $result = $extrafields->fetch_name_optionals_label($elementtype, false, $attrname);
1220  if (!$result) {
1221  throw new RestException(404, 'Extrafield not found from attrname and elementtype');
1222  }
1223 
1224  if (!$extrafields->delete($attrname, $elementtype)) {
1225  throw new RestException(500, 'Error when delete extrafield : '.$extrafields->error);
1226  }
1227 
1228  return array(
1229  'success' => array(
1230  'code' => 200,
1231  'message' => 'Extrafield deleted from attrname and elementtype'
1232  )
1233  );
1234  }
1235 
1236 
1237 
1249  public function getExtrafields($attrname, $elementtype)
1250  {
1251  $answer = array();
1252 
1253  if (!DolibarrApiAccess::$user->admin) {
1254  throw new RestException(403, 'Only an admin user can get list of extrafields');
1255  }
1256 
1257  if ($elementtype == 'thirdparty') {
1258  $elementtype = 'societe';
1259  }
1260  if ($elementtype == 'contact') {
1261  $elementtype = 'socpeople';
1262  }
1263 
1264  $sql = "SELECT t.rowid as id, t.name, t.entity, t.elementtype, t.label, t.type, t.size, t.fieldcomputed, t.fielddefault,";
1265  $sql .= " t.fieldunique, t.fieldrequired, t.perms, t.enabled, t.pos, t.alwayseditable, t.param, t.list, t.printable,";
1266  $sql .= " t.totalizable, t.langs, t.help, t.css, t.cssview, t.fk_user_author, t.fk_user_modif, t.datec, t.tms";
1267  $sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
1268  $sql .= " WHERE t.entity IN (".getEntity('extrafields').")";
1269  $sql .= " AND t.elementtype = '".$this->db->escape($elementtype)."'";
1270  $sql .= " AND t.name = '".$this->db->escape($attrname)."'";
1271 
1272  $resql = $this->db->query($sql);
1273  if ($resql) {
1274  if ($this->db->num_rows($resql)) {
1275  while ($tab = $this->db->fetch_object($resql)) {
1276  // New usage
1277  $answer[$tab->elementtype][$tab->name]['id'] = $tab->id;
1278  $answer[$tab->elementtype][$tab->name]['type'] = $tab->type;
1279  $answer[$tab->elementtype][$tab->name]['label'] = $tab->label;
1280  $answer[$tab->elementtype][$tab->name]['size'] = $tab->size;
1281  $answer[$tab->elementtype][$tab->name]['elementtype'] = $tab->elementtype;
1282  $answer[$tab->elementtype][$tab->name]['default'] = $tab->fielddefault;
1283  $answer[$tab->elementtype][$tab->name]['computed'] = $tab->fieldcomputed;
1284  $answer[$tab->elementtype][$tab->name]['unique'] = $tab->fieldunique;
1285  $answer[$tab->elementtype][$tab->name]['required'] = $tab->fieldrequired;
1286  $answer[$tab->elementtype][$tab->name]['param'] = ($tab->param ? jsonOrUnserialize($tab->param) : ''); // This may be a string encoded with serialise() or json_encode()
1287  $answer[$tab->elementtype][$tab->name]['pos'] = $tab->pos;
1288  $answer[$tab->elementtype][$tab->name]['alwayseditable'] = $tab->alwayseditable;
1289  $answer[$tab->elementtype][$tab->name]['perms'] = $tab->perms;
1290  $answer[$tab->elementtype][$tab->name]['list'] = $tab->list;
1291  $answer[$tab->elementtype][$tab->name]['printable'] = $tab->printable;
1292  $answer[$tab->elementtype][$tab->name]['totalizable'] = $tab->totalizable;
1293  $answer[$tab->elementtype][$tab->name]['langs'] = $tab->langs;
1294  $answer[$tab->elementtype][$tab->name]['help'] = $tab->help;
1295  $answer[$tab->elementtype][$tab->name]['css'] = $tab->css;
1296  $answer[$tab->elementtype][$tab->name]['cssview'] = $tab->cssview;
1297  $answer[$tab->elementtype][$tab->name]['csslist'] = $tab->csslist;
1298  $answer[$tab->elementtype][$tab->name]['fk_user_author'] = $tab->fk_user_author;
1299  $answer[$tab->elementtype][$tab->name]['fk_user_modif'] = $tab->fk_user_modif;
1300  $answer[$tab->elementtype][$tab->name]['datec'] = $tab->datec;
1301  $answer[$tab->elementtype][$tab->name]['tms'] = $tab->tms;
1302  }
1303  } else {
1304  throw new RestException(404, 'Extrafield not found from attrname and elementtype');
1305  }
1306  } else {
1307  throw new RestException(503, 'Error when retrieving list of extra fields : '.$this->db->lasterror());
1308  }
1309 
1310  return $answer;
1311  }
1312 
1326  public function postExtrafields($attrname, $elementtype, $request_data = null)
1327  {
1328  if (!DolibarrApiAccess::$user->admin) {
1329  throw new RestException(403, 'Only an admin user can create an extrafield');
1330  }
1331 
1332  $extrafields = new ExtraFields($this->db);
1333 
1334  $result = $extrafields->fetch_name_optionals_label($elementtype, false, $attrname);
1335  if ($result) {
1336  throw new RestException(409, 'Duplicate extrafield already found from attrname and elementtype');
1337  }
1338 
1339  // Check mandatory fields is not working despise being a modified copy from api_thirdparties.class.php
1340  // $result = $this->_validateExtrafields($request_data, $extrafields);
1341 
1342  foreach ($request_data as $field => $value) {
1343  $extrafields->$field = $this->_checkValForAPI($field, $value, $extrafields);
1344  }
1345 
1346  $entity = DolibarrApiAccess::$user->entity;
1347  if (empty($entity)) {
1348  $entity = 1;
1349  }
1350 
1351  // built in validation
1352  $enabled = 1; // hardcoded because it seems to always be 1 in every row in the database
1353 
1354  if ($request_data['label']) {
1355  $label = $request_data['label'];
1356  } else {
1357  throw new RestException(400, "label field absent in json at root level");
1358  }
1359 
1360  $alwayseditable = $request_data['alwayseditable'];
1361  $default_value = $request_data['default_value'];
1362  $totalizable = $request_data['totalizable'];
1363  $printable = $request_data['printable'];
1364  $required = $request_data['required'];
1365  $langfile = $request_data['langfile'];
1366  $computed = $request_data['computed'];
1367  $unique = $request_data['unique'];
1368  $param = $request_data['param'];
1369  $perms = $request_data['perms'];
1370  $size = $request_data['size'];
1371  $type = $request_data['type'];
1372  $list = $request_data['list'];
1373  $help = $request_data['help'];
1374  $pos = $request_data['pos'];
1375  $moreparams = array();
1376 
1377  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)) {
1378  throw new RestException(500, 'Error creating extrafield', array_merge(array($extrafields->errno), $extrafields->errors));
1379  }
1380 
1381  $sql = "SELECT t.rowid as id";
1382  $sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
1383  $sql .= " WHERE elementtype = '".$this->db->escape($elementtype)."'";
1384  $sql .= " AND name = '".$this->db->escape($attrname)."'";
1385 
1386  $resql = $this->db->query($sql);
1387  if ($resql) {
1388  if ($this->db->num_rows($resql)) {
1389  $tab = $this->db->fetch_object($resql);
1390  $id = (int) $tab->id;
1391  } else {
1392  $id = (int) -1;
1393  }
1394  } else {
1395  $id = (int) -2;
1396  }
1397 
1398  return $id;
1399  }
1400 
1415  public function updateExtrafields($attrname, $elementtype, $request_data = null)
1416  {
1417  if (!DolibarrApiAccess::$user->admin) {
1418  throw new RestException(403, 'Only an admin user can create an extrafield');
1419  }
1420 
1421  $extrafields = new ExtraFields($this->db);
1422 
1423  $result = $extrafields->fetch_name_optionals_label($elementtype, false, $attrname);
1424  if (!$result) {
1425  throw new RestException(404, 'Extrafield not found from attrname and elementtype');
1426  }
1427 
1428  foreach ($request_data as $field => $value) {
1429  $extrafields->$field = $this->_checkValForAPI($field, $value, $extrafields);
1430  }
1431 
1432  $entity = DolibarrApiAccess::$user->entity;
1433  if (empty($entity)) {
1434  $entity = 1;
1435  }
1436 
1437  // built in validation
1438  $enabled = 1; // hardcoded because it seems to always be 1 in every row in the database
1439  if ($request_data['label']) {
1440  $label = $request_data['label'];
1441  } else {
1442  throw new RestException(400, "label field absent in json at root level");
1443  }
1444 
1445  $alwayseditable = $request_data['alwayseditable'];
1446  $default_value = $request_data['default_value'];
1447  $totalizable = $request_data['totalizable'];
1448  $printable = $request_data['printable'];
1449  $required = $request_data['required'];
1450  $langfile = $request_data['langfile'];
1451  $computed = $request_data['computed'];
1452  $unique = $request_data['unique'];
1453  $param = $request_data['param'];
1454  $perms = $request_data['perms'];
1455  $size = $request_data['size'];
1456  $type = $request_data['type'];
1457  $list = $request_data['list'];
1458  $help = $request_data['help'];
1459  $pos = $request_data['pos'];
1460  $moreparams = array();
1461 
1462  dol_syslog(get_class($this).'::updateExtraField', LOG_DEBUG);
1463  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)) {
1464  throw new RestException(500, 'Error updating extrafield', array_merge(array($extrafields->errno), $extrafields->errors));
1465  }
1466 
1467  $sql = "SELECT t.rowid as id";
1468  $sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
1469  $sql .= " WHERE elementtype = '".$this->db->escape($elementtype)."'";
1470  $sql .= " AND name = '".$this->db->escape($attrname)."'";
1471 
1472  $resql = $this->db->query($sql);
1473  if ($resql) {
1474  if ($this->db->num_rows($resql)) {
1475  $tab = $this->db->fetch_object($resql);
1476  $id = (int) $tab->id;
1477  } else {
1478  $id = (int) -1;
1479  }
1480  } else {
1481  $id = (int) -2;
1482  }
1483 
1484  return $id;
1485  }
1486 
1505  public function getListOfTowns($sortfield = "zip,town", $sortorder = 'ASC', $limit = 100, $page = 0, $zipcode = '', $town = '', $active = 1, $sqlfilters = '')
1506  {
1507  $list = array();
1508 
1509  $sql = "SELECT rowid AS id, zip, town, fk_county, fk_pays AS fk_country";
1510  $sql .= " FROM ".MAIN_DB_PREFIX."c_ziptown as t";
1511  $sql .= " WHERE t.active = ".((int) $active);
1512  if ($zipcode) {
1513  $sql .= " AND t.zip LIKE '%".$this->db->escape($zipcode)."%'";
1514  }
1515  if ($town) {
1516  $sql .= " AND t.town LIKE '%".$this->db->escape($town)."%'";
1517  }
1518  // Add sql filters
1519  if ($sqlfilters) {
1520  $errormessage = '';
1521  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1522  if ($errormessage) {
1523  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1524  }
1525  }
1526 
1527 
1528  $sql .= $this->db->order($sortfield, $sortorder);
1529 
1530  if ($limit) {
1531  if ($page < 0) {
1532  $page = 0;
1533  }
1534  $offset = $limit * $page;
1535 
1536  $sql .= $this->db->plimit($limit, $offset);
1537  }
1538 
1539  $result = $this->db->query($sql);
1540 
1541  if ($result) {
1542  $num = $this->db->num_rows($result);
1543  $min = min($num, ($limit <= 0 ? $num : $limit));
1544  for ($i = 0; $i < $min; $i++) {
1545  $list[] = $this->db->fetch_object($result);
1546  }
1547  } else {
1548  throw new RestException(503, 'Error when retrieving list of towns : '.$this->db->lasterror());
1549  }
1550 
1551  return $list;
1552  }
1553 
1572  public function getPaymentTerms($sortfield = "sortorder", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1573  {
1574  $list = array();
1575 
1576  if (!DolibarrApiAccess::$user->hasRight('propal', 'lire') && !DolibarrApiAccess::$user->hasRight('commande', 'lire') && !DolibarrApiAccess::$user->hasRight('facture', 'lire')) {
1577  throw new RestException(403);
1578  }
1579 
1580  $sql = "SELECT rowid as id, code, sortorder, libelle as label, libelle_facture as descr, type_cdr, nbjour, decalage, module";
1581  $sql .= " FROM ".MAIN_DB_PREFIX."c_payment_term as t";
1582  $sql .= " WHERE t.entity IN (".getEntity('c_payment_term').")";
1583  $sql .= " AND t.active = ".((int) $active);
1584  // Add sql filters
1585  if ($sqlfilters) {
1586  $errormessage = '';
1587  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1588  if ($errormessage) {
1589  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1590  }
1591  }
1592 
1593 
1594  $sql .= $this->db->order($sortfield, $sortorder);
1595 
1596  if ($limit) {
1597  if ($page < 0) {
1598  $page = 0;
1599  }
1600  $offset = $limit * $page;
1601 
1602  $sql .= $this->db->plimit($limit, $offset);
1603  }
1604 
1605  $result = $this->db->query($sql);
1606 
1607  if ($result) {
1608  $num = $this->db->num_rows($result);
1609  $min = min($num, ($limit <= 0 ? $num : $limit));
1610  for ($i = 0; $i < $min; $i++) {
1611  $list[] = $this->db->fetch_object($result);
1612  }
1613  } else {
1614  throw new RestException(503, $this->db->lasterror());
1615  }
1616 
1617  return $list;
1618  }
1619 
1636  public function getShippingModes($limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
1637  {
1638  $list = array();
1639 
1640  $sql = "SELECT rowid as id, code, libelle as label, description, tracking, module";
1641  $sql .= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as t";
1642  $sql .= " WHERE t.entity IN (".getEntity('c_shipment_mode').")";
1643  $sql .= " AND t.active = ".((int) $active);
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  $method = $this->db->fetch_object($result);
1672  $this->translateLabel($method, $lang, '', array('dict'));
1673  $list[] = $method;
1674  }
1675  } else {
1676  throw new RestException(503, $this->db->lasterror());
1677  }
1678 
1679  return $list;
1680  }
1681 
1698  public function getListOfMeasuringUnits($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1699  {
1700  $list = array();
1701 
1702  $sql = "SELECT t.rowid, t.code, t.label,t.short_label, t.active, t.scale, t.unit_type";
1703  $sql .= " FROM ".MAIN_DB_PREFIX."c_units as t";
1704  $sql .= " WHERE t.active = ".((int) $active);
1705  // Add sql filters
1706  if ($sqlfilters) {
1707  $errormessage = '';
1708  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1709  if ($errormessage) {
1710  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1711  }
1712  }
1713 
1714 
1715  $sql .= $this->db->order($sortfield, $sortorder);
1716 
1717  if ($limit) {
1718  if ($page < 0) {
1719  $page = 0;
1720  }
1721  $offset = $limit * $page;
1722 
1723  $sql .= $this->db->plimit($limit, $offset);
1724  }
1725 
1726  $result = $this->db->query($sql);
1727 
1728  if ($result) {
1729  $num = $this->db->num_rows($result);
1730  $min = min($num, ($limit <= 0 ? $num : $limit));
1731  for ($i = 0; $i < $min; $i++) {
1732  $list[] = $this->db->fetch_object($result);
1733  }
1734  } else {
1735  throw new RestException(503, 'Error when retrieving list of measuring units: '.$this->db->lasterror());
1736  }
1737 
1738  return $list;
1739  }
1740 
1758  public function getListOfLegalForm($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $active = 1, $sqlfilters = '')
1759  {
1760  $list = array();
1761 
1762  $sql = "SELECT t.rowid, t.code, t.fk_pays, t.libelle, t.isvatexempted, t.active, t.module, t.position";
1763  $sql .= " FROM ".MAIN_DB_PREFIX."c_forme_juridique as t";
1764  $sql .= " WHERE t.active = ".((int) $active);
1765  if ($country) {
1766  $sql .= " AND t.fk_pays = ".((int) $country);
1767  }
1768  // Add sql filters
1769  if ($sqlfilters) {
1770  $errormessage = '';
1771  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1772  if ($errormessage) {
1773  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1774  }
1775  }
1776 
1777 
1778  $sql .= $this->db->order($sortfield, $sortorder);
1779 
1780  if ($limit) {
1781  if ($page < 0) {
1782  $page = 0;
1783  }
1784  $offset = $limit * $page;
1785 
1786  $sql .= $this->db->plimit($limit, $offset);
1787  }
1788 
1789  $result = $this->db->query($sql);
1790 
1791  if ($result) {
1792  $num = $this->db->num_rows($result);
1793  $min = min($num, ($limit <= 0 ? $num : $limit));
1794  for ($i = 0; $i < $min; $i++) {
1795  $list[] = $this->db->fetch_object($result);
1796  }
1797  } else {
1798  throw new RestException(503, 'Error when retrieving list of legal form: '.$this->db->lasterror());
1799  }
1800 
1801  return $list;
1802  }
1803 
1820  public function getListOfStaff($sortfield = "id", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1821  {
1822  $list = array();
1823 
1824  $sql = "SELECT t.id, t.code, t.libelle, t.active, t.module";
1825  $sql .= " FROM ".MAIN_DB_PREFIX."c_effectif as t";
1826  $sql .= " WHERE t.active = ".((int) $active);
1827  // Add sql filters
1828  if ($sqlfilters) {
1829  $errormessage = '';
1830  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1831  if ($errormessage) {
1832  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1833  }
1834  }
1835 
1836 
1837  $sql .= $this->db->order($sortfield, $sortorder);
1838 
1839  if ($limit) {
1840  if ($page < 0) {
1841  $page = 0;
1842  }
1843  $offset = $limit * $page;
1844 
1845  $sql .= $this->db->plimit($limit, $offset);
1846  }
1847 
1848  $result = $this->db->query($sql);
1849 
1850  if ($result) {
1851  $num = $this->db->num_rows($result);
1852  $min = min($num, ($limit <= 0 ? $num : $limit));
1853  for ($i = 0; $i < $min; $i++) {
1854  $list[] = $this->db->fetch_object($result);
1855  }
1856  } else {
1857  throw new RestException(503, 'Error when retrieving list of staff: '.$this->db->lasterror());
1858  }
1859 
1860  return $list;
1861  }
1862 
1879  public function getListOfsocialNetworks($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '')
1880  {
1881  global $conf;
1882 
1883  if (!isModEnabled('socialnetworks')) {
1884  throw new RestException(400, 'API not available: this dictionary is not enabled by setup');
1885  }
1886 
1887  $list = array();
1888  //TODO link with multicurrency module
1889  $sql = "SELECT t.rowid, t.entity, t.code, t.label, t.url, t.icon, t.active";
1890  $sql .= " FROM ".MAIN_DB_PREFIX."c_socialnetworks as t";
1891  $sql .= " WHERE t.entity IN (".getEntity('c_socialnetworks').")";
1892  $sql .= " AND t.active = ".((int) $active);
1893  // Add sql filters
1894  if ($sqlfilters) {
1895  $errormessage = '';
1896  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1897  if ($errormessage) {
1898  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1899  }
1900  }
1901 
1902 
1903  $sql .= $this->db->order($sortfield, $sortorder);
1904 
1905  if ($limit) {
1906  if ($page < 0) {
1907  $page = 0;
1908  }
1909  $offset = $limit * $page;
1910 
1911  $sql .= $this->db->plimit($limit, $offset);
1912  }
1913 
1914  $result = $this->db->query($sql);
1915 
1916  if ($result) {
1917  $num = $this->db->num_rows($result);
1918  $min = min($num, ($limit <= 0 ? $num : $limit));
1919  for ($i = 0; $i < $min; $i++) {
1920  $list[] = $this->db->fetch_object($result);
1921  }
1922  } else {
1923  throw new RestException(503, 'Error when retrieving list of social networks: '.$this->db->lasterror());
1924  }
1925 
1926  return $list;
1927  }
1928 
1946  public function getTicketsCategories($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
1947  {
1948  $list = array();
1949 
1950  $sql = "SELECT rowid, code, pos, label, use_default, description";
1951  $sql .= " FROM ".MAIN_DB_PREFIX."c_ticket_category as t";
1952  $sql .= " WHERE t.entity IN (".getEntity('c_ticket_category').")";
1953  $sql .= " AND t.active = ".((int) $active);
1954  // Add sql filters
1955  if ($sqlfilters) {
1956  $errormessage = '';
1957  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
1958  if ($errormessage) {
1959  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
1960  }
1961  }
1962 
1963 
1964  $sql .= $this->db->order($sortfield, $sortorder);
1965 
1966  if ($limit) {
1967  if ($page < 0) {
1968  $page = 0;
1969  }
1970  $offset = $limit * $page;
1971 
1972  $sql .= $this->db->plimit($limit, $offset);
1973  }
1974 
1975  $result = $this->db->query($sql);
1976 
1977  if ($result) {
1978  $num = $this->db->num_rows($result);
1979  $min = min($num, ($limit <= 0 ? $num : $limit));
1980  for ($i = 0; $i < $min; $i++) {
1981  $category = $this->db->fetch_object($result);
1982  $this->translateLabel($category, $lang, 'TicketCategoryShort', array('ticket'));
1983  $list[] = $category;
1984  }
1985  } else {
1986  throw new RestException(503, 'Error when retrieving list of ticket categories : '.$this->db->lasterror());
1987  }
1988 
1989  return $list;
1990  }
1991 
2009  public function getTicketsSeverities($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
2010  {
2011  $list = array();
2012 
2013  $sql = "SELECT rowid, code, pos, label, use_default, color, description";
2014  $sql .= " FROM ".MAIN_DB_PREFIX."c_ticket_severity as t";
2015  $sql .= " WHERE t.entity IN (".getEntity('c_ticket_severity').")";
2016  $sql .= " AND t.active = ".((int) $active);
2017  // Add sql filters
2018  if ($sqlfilters) {
2019  $errormessage = '';
2020  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
2021  if ($errormessage) {
2022  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
2023  }
2024  }
2025 
2026 
2027  $sql .= $this->db->order($sortfield, $sortorder);
2028 
2029  if ($limit) {
2030  if ($page < 0) {
2031  $page = 0;
2032  }
2033  $offset = $limit * $page;
2034 
2035  $sql .= $this->db->plimit($limit, $offset);
2036  }
2037 
2038  $result = $this->db->query($sql);
2039 
2040  if ($result) {
2041  $num = $this->db->num_rows($result);
2042  $min = min($num, ($limit <= 0 ? $num : $limit));
2043  for ($i = 0; $i < $min; $i++) {
2044  $severity = $this->db->fetch_object($result);
2045  $this->translateLabel($severity, $lang, 'TicketSeverityShort', array('ticket'));
2046  $list[] = $severity;
2047  }
2048  } else {
2049  throw new RestException(503, 'Error when retrieving list of ticket severities : '.$this->db->lasterror());
2050  }
2051 
2052  return $list;
2053  }
2054 
2072  public function getTicketsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
2073  {
2074  $list = array();
2075 
2076  $sql = "SELECT rowid, code, pos, label, use_default, description";
2077  $sql .= " FROM ".MAIN_DB_PREFIX."c_ticket_type as t";
2078  $sql .= " WHERE t.entity IN (".getEntity('c_ticket_type').")";
2079  $sql .= " AND t.active = ".((int) $active);
2080 
2081  // Add sql filters
2082  if ($sqlfilters) {
2083  $errormessage = '';
2084  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
2085  if ($errormessage) {
2086  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
2087  }
2088  }
2089 
2090 
2091  $sql .= $this->db->order($sortfield, $sortorder);
2092 
2093  if ($limit) {
2094  if ($page < 0) {
2095  $page = 0;
2096  }
2097  $offset = $limit * $page;
2098 
2099  $sql .= $this->db->plimit($limit, $offset);
2100  }
2101 
2102  $result = $this->db->query($sql);
2103 
2104  if ($result) {
2105  $num = $this->db->num_rows($result);
2106  $min = min($num, ($limit <= 0 ? $num : $limit));
2107  for ($i = 0; $i < $min; $i++) {
2108  $type =$this->db->fetch_object($result);
2109  $this->translateLabel($type, $lang, 'TicketTypeShort', array('ticket'));
2110  $list[] = $type;
2111  }
2112  } else {
2113  throw new RestException(503, 'Error when retrieving list of ticket types : '.$this->db->lasterror());
2114  }
2115 
2116  return $list;
2117  }
2118 
2135  public function getListOfIncoterms($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $lang = '', $sqlfilters = '')
2136  {
2137  $list = array();
2138 
2139  $sql = "SELECT rowid, code, active";
2140  $sql .= " FROM ".MAIN_DB_PREFIX."c_incoterms as t";
2141  $sql .= " WHERE 1=1";
2142 
2143  // Add sql filters
2144  if ($sqlfilters) {
2145  $errormessage = '';
2146  if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
2147  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
2148  }
2149  $regexstring = '\‍(([^:\'\‍(\‍)]+:[^:\'\‍(\‍)]+:[^\‍(\‍)]+)\‍)';
2150  $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
2151  }
2152 
2153 
2154  $sql .= $this->db->order($sortfield, $sortorder);
2155 
2156  if ($limit) {
2157  if ($page < 0) {
2158  $page = 0;
2159  }
2160  $offset = $limit * $page;
2161 
2162  $sql .= $this->db->plimit($limit, $offset);
2163  }
2164 
2165  $result = $this->db->query($sql);
2166 
2167  if ($result) {
2168  $num = $this->db->num_rows($result);
2169  $min = min($num, ($limit <= 0 ? $num : $limit));
2170  for ($i = 0; $i < $min; $i++) {
2171  $type =$this->db->fetch_object($result);
2172  $list[] = $type;
2173  }
2174  } else {
2175  throw new RestException(503, 'Error when retrieving list of incoterm types : '.$this->db->lasterror());
2176  }
2177 
2178  return $list;
2179  }
2180 
2190  public function getCompany()
2191  {
2192  global $conf, $mysoc;
2193 
2194  if (!DolibarrApiAccess::$user->admin
2195  && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_COMPANY') || DolibarrApiAccess::$user->login != $conf->global->API_LOGINS_ALLOWED_FOR_GET_COMPANY)) {
2196  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');
2197  }
2198 
2199  unset($mysoc->pays);
2200  unset($mysoc->note);
2201  unset($mysoc->nom);
2202 
2203  unset($mysoc->lines);
2204 
2205  unset($mysoc->effectif);
2206  unset($mysoc->effectif_id);
2207  unset($mysoc->forme_juridique_code);
2208  unset($mysoc->forme_juridique);
2209  unset($mysoc->mode_reglement_supplier_id);
2210  unset($mysoc->cond_reglement_supplier_id);
2211  unset($mysoc->transport_mode_supplier_id);
2212  unset($mysoc->fk_prospectlevel);
2213 
2214  unset($mysoc->total_ht);
2215  unset($mysoc->total_tva);
2216  unset($mysoc->total_localtax1);
2217  unset($mysoc->total_localtax2);
2218  unset($mysoc->total_ttc);
2219 
2220  unset($mysoc->lastname);
2221  unset($mysoc->firstname);
2222  unset($mysoc->civility_id);
2223 
2224  unset($mysoc->client);
2225  unset($mysoc->prospect);
2226  unset($mysoc->fournisseur);
2227  unset($mysoc->contact_id);
2228 
2229  unset($mysoc->fk_incoterms);
2230  unset($mysoc->label_incoterms);
2231  unset($mysoc->location_incoterms);
2232 
2233  return $this->_cleanObjectDatas($mysoc);
2234  }
2235 
2245  public function getEstablishments()
2246  {
2247  $list = array();
2248 
2249  $limit = 0;
2250 
2251  $sql = "SELECT e.rowid, e.rowid as ref, e.label, e.address, e.zip, e.town, e.status";
2252  $sql .= " FROM ".MAIN_DB_PREFIX."establishment as e";
2253  $sql .= " WHERE e.entity IN (".getEntity('establishment').')';
2254  // if ($type) $sql .= " AND t.type LIKE '%".$this->db->escape($type)."%'";
2255  // if ($module) $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'";
2256  // Add sql filters
2257 
2258  $result = $this->db->query($sql);
2259 
2260  if ($result) {
2261  $num = $this->db->num_rows($result);
2262  $min = min($num, ($limit <= 0 ? $num : $limit));
2263  for ($i = 0; $i < $min; $i++) {
2264  $list[] = $this->db->fetch_object($result);
2265  }
2266  } else {
2267  throw new RestException(503, 'Error when retrieving list of establishments : '.$this->db->lasterror());
2268  }
2269 
2270  return $list;
2271  }
2272 
2284  public function getEtablishmentByID($id)
2285  {
2286  $establishment = new Establishment($this->db);
2287 
2288  $result = $establishment->fetch($id);
2289  if ($result < 0) {
2290  throw new RestException(503, 'Error when retrieving establishment : '.$establishment->error);
2291  } elseif ($result == 0) {
2292  throw new RestException(404, 'Establishment not found');
2293  }
2294 
2295  return $this->_cleanObjectDatas($establishment);
2296  }
2297 
2311  public function getConf($constantname)
2312  {
2313  global $conf;
2314 
2315  if (!DolibarrApiAccess::$user->admin
2316  && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_CONST_READ') || DolibarrApiAccess::$user->login != getDolGlobalString('API_LOGINS_ALLOWED_FOR_CONST_READ'))) {
2317  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');
2318  }
2319 
2320  if (!preg_match('/^[a-zA-Z0-9_]+$/', $constantname) || !isset($conf->global->$constantname)) {
2321  throw new RestException(400, 'Error Bad or unknown value for constantname');
2322  }
2323  if (isASecretKey($constantname)) {
2324  throw new RestException(403, 'Forbidden. This parameter can not be read with APIs');
2325  }
2326 
2327  return getDolGlobalString($constantname);
2328  }
2329 
2342  public function getCheckIntegrity($target)
2343  {
2344  global $langs, $conf;
2345 
2346  if (!DolibarrApiAccess::$user->admin
2347  && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_INTEGRITY_CHECK') || DolibarrApiAccess::$user->login != $conf->global->API_LOGINS_ALLOWED_FOR_INTEGRITY_CHECK)) {
2348  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');
2349  }
2350 
2351  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
2352  require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
2353 
2354  $langs->load("admin");
2355 
2356  $outexpectedchecksum = '';
2357  $outcurrentchecksum = '';
2358 
2359  // Modified or missing files
2360  $file_list = array('missing' => array(), 'updated' => array());
2361 
2362  // Local file to compare to
2363  $xmlshortfile = dol_sanitizeFileName('filelist-'.DOL_VERSION.getDolGlobalString('MAIN_FILECHECK_LOCAL_SUFFIX').'.xml'.getDolGlobalString('MAIN_FILECHECK_LOCAL_EXT'));
2364 
2365  $xmlfile = DOL_DOCUMENT_ROOT.'/install/'.$xmlshortfile;
2366  if (!preg_match('/\.zip$/i', $xmlfile) && dol_is_file($xmlfile.'.zip')) {
2367  $xmlfile = $xmlfile.'.zip';
2368  }
2369 
2370  // Remote file to compare to
2371  $xmlremote = (($target == 'default' || $target == 'local') ? '' : $target);
2372  if (empty($xmlremote) && getDolGlobalString('MAIN_FILECHECK_URL')) {
2373  $xmlremote = getDolGlobalString('MAIN_FILECHECK_URL');
2374  }
2375  $param = 'MAIN_FILECHECK_URL_'.DOL_VERSION;
2376  if (empty($xmlremote) && getDolGlobalString($param)) {
2377  $xmlremote = getDolGlobalString($param);
2378  }
2379  if (empty($xmlremote)) {
2380  $xmlremote = 'https://www.dolibarr.org/files/stable/signatures/filelist-'.DOL_VERSION.'.xml';
2381  }
2382  if ($xmlremote && !preg_match('/^https?:\/\//i', $xmlremote)) {
2383  $langs->load("errors");
2384  throw new RestException(500, $langs->trans("ErrorURLMustStartWithHttp", $xmlremote));
2385  }
2386  if ($xmlremote && !preg_match('/\.xml$/', $xmlremote)) {
2387  $langs->load("errors");
2388  throw new RestException(500, $langs->trans("ErrorURLMustEndWith", $xmlremote, '.xml'));
2389  }
2390 
2391  if (LIBXML_VERSION < 20900) {
2392  // Avoid load of external entities (security problem).
2393  // Required only if LIBXML_VERSION < 20900
2394  // @phan-suppress-next-line PhanDeprecatedFunctionInternal
2395  libxml_disable_entity_loader(true);
2396  }
2397 
2398  if ($target == 'local') {
2399  if (dol_is_file($xmlfile)) {
2400  $xml = simplexml_load_file($xmlfile);
2401  } else {
2402  throw new RestException(500, $langs->trans('XmlNotFound').': /install/'.$xmlshortfile);
2403  }
2404  } else {
2405  $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.
2406 
2407  // Return array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...)
2408  if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != '400' && $xmlarray['http_code'] != '404') {
2409  $xmlfile = $xmlarray['content'];
2410  //print "xmlfilestart".$xmlfile."endxmlfile";
2411  $xml = simplexml_load_string($xmlfile, 'SimpleXMLElement', LIBXML_NOCDATA|LIBXML_NONET);
2412  } else {
2413  $errormsg = $langs->trans('XmlNotFound').': '.$xmlremote.' - '.$xmlarray['http_code'].(($xmlarray['http_code'] == 400 && $xmlarray['content']) ? ' '.$xmlarray['content'] : '').' '.$xmlarray['curl_error_no'].' '.$xmlarray['curl_error_msg'];
2414  throw new RestException(500, $errormsg);
2415  }
2416  }
2417 
2418  if ($xml) {
2419  $checksumconcat = array();
2420  $file_list = array();
2421  $out = '';
2422 
2423  // Forced constants
2424  if (is_object($xml->dolibarr_constants[0])) {
2425  $out .= load_fiche_titre($langs->trans("ForcedConstants"));
2426 
2427  $out .= '<div class="div-table-responsive-no-min">';
2428  $out .= '<table class="noborder">';
2429  $out .= '<tr class="liste_titre">';
2430  $out .= '<td>#</td>';
2431  $out .= '<td>'.$langs->trans("Constant").'</td>';
2432  $out .= '<td class="center">'.$langs->trans("ExpectedValue").'</td>';
2433  $out .= '<td class="center">'.$langs->trans("Value").'</td>';
2434  $out .= '</tr>'."\n";
2435 
2436  $i = 0;
2437  foreach ($xml->dolibarr_constants[0]->constant as $constant) { // $constant is a simpleXMLElement
2438  $constname = $constant['name'];
2439  $constvalue = (string) $constant;
2440  $constvalue = (empty($constvalue) ? '0' : $constvalue);
2441  // Value found
2442  $value = '';
2443  if ($constname && getDolGlobalString($constname) != '') {
2444  $value = getDolGlobalString($constname);
2445  }
2446  $valueforchecksum = (empty($value) ? '0' : $value);
2447 
2448  $checksumconcat[] = $valueforchecksum;
2449 
2450  $i++;
2451  $out .= '<tr class="oddeven">';
2452  $out .= '<td>'.$i.'</td>'."\n";
2453  $out .= '<td>'.dol_escape_htmltag($constname).'</td>'."\n";
2454  $out .= '<td class="center">'.dol_escape_htmltag($constvalue).'</td>'."\n";
2455  $out .= '<td class="center">'.dol_escape_htmltag($valueforchecksum).'</td>'."\n";
2456  $out .= "</tr>\n";
2457  }
2458 
2459  if ($i == 0) {
2460  $out .= '<tr class="oddeven"><td colspan="4" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
2461  }
2462  $out .= '</table>';
2463  $out .= '</div>';
2464 
2465  $out .= '<br>';
2466  }
2467 
2468  // Scan htdocs
2469  if (is_object($xml->dolibarr_htdocs_dir[0])) {
2470  $includecustom = (empty($xml->dolibarr_htdocs_dir[0]['includecustom']) ? 0 : $xml->dolibarr_htdocs_dir[0]['includecustom']);
2471 
2472  // Define qualified files (must be same than into generate_filelist_xml.php and in api_setup.class.php)
2473  $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)$';
2474  $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
2475  $scanfiles = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude);
2476 
2477  // Fill file_list with files in signature, new files, modified files
2478  $ret = getFilesUpdated($file_list, $xml->dolibarr_htdocs_dir[0], '', DOL_DOCUMENT_ROOT, $checksumconcat); // Fill array $file_list
2479  // Complete with list of new files
2480  foreach ($scanfiles as $keyfile => $valfile) {
2481  $tmprelativefilename = preg_replace('/^'.preg_quote(DOL_DOCUMENT_ROOT, '/').'/', '', $valfile['fullname']);
2482  if (!in_array($tmprelativefilename, $file_list['insignature'])) {
2483  $md5newfile = @md5_file($valfile['fullname']); // Can fails if we don't have permission to open/read file
2484  $file_list['added'][] = array('filename'=>$tmprelativefilename, 'md5'=>$md5newfile);
2485  }
2486  }
2487 
2488  // Files missing
2489  $out .= load_fiche_titre($langs->trans("FilesMissing"));
2490 
2491  $out .= '<div class="div-table-responsive-no-min">';
2492  $out .= '<table class="noborder">';
2493  $out .= '<tr class="liste_titre">';
2494  $out .= '<td>#</td>';
2495  $out .= '<td>'.$langs->trans("Filename").'</td>';
2496  $out .= '<td class="center">'.$langs->trans("ExpectedChecksum").'</td>';
2497  $out .= '</tr>'."\n";
2498  $tmpfilelist = dol_sort_array($file_list['missing'], 'filename');
2499  if (is_array($tmpfilelist) && count($tmpfilelist)) {
2500  $i = 0;
2501  foreach ($tmpfilelist as $file) {
2502  $i++;
2503  $out .= '<tr class="oddeven">';
2504  $out .= '<td>'.$i.'</td>'."\n";
2505  $out .= '<td>'.dol_escape_htmltag($file['filename']).'</td>'."\n";
2506  $out .= '<td class="center">'.$file['expectedmd5'].'</td>'."\n";
2507  $out .= "</tr>\n";
2508  }
2509  } else {
2510  $out .= '<tr class="oddeven"><td colspan="3" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
2511  }
2512  $out .= '</table>';
2513  $out .= '</div>';
2514 
2515  $out .= '<br>';
2516 
2517  // Files modified
2518  $out .= load_fiche_titre($langs->trans("FilesModified"));
2519 
2520  $totalsize = 0;
2521  $out .= '<div class="div-table-responsive-no-min">';
2522  $out .= '<table class="noborder">';
2523  $out .= '<tr class="liste_titre">';
2524  $out .= '<td>#</td>';
2525  $out .= '<td>'.$langs->trans("Filename").'</td>';
2526  $out .= '<td class="center">'.$langs->trans("ExpectedChecksum").'</td>';
2527  $out .= '<td class="center">'.$langs->trans("CurrentChecksum").'</td>';
2528  $out .= '<td class="right">'.$langs->trans("Size").'</td>';
2529  $out .= '<td class="right">'.$langs->trans("DateModification").'</td>';
2530  $out .= '</tr>'."\n";
2531  $tmpfilelist2 = dol_sort_array($file_list['updated'], 'filename');
2532  if (is_array($tmpfilelist2) && count($tmpfilelist2)) {
2533  $i = 0;
2534  foreach ($tmpfilelist2 as $file) {
2535  $i++;
2536  $out .= '<tr class="oddeven">';
2537  $out .= '<td>'.$i.'</td>'."\n";
2538  $out .= '<td>'.dol_escape_htmltag($file['filename']).'</td>'."\n";
2539  $out .= '<td class="center">'.$file['expectedmd5'].'</td>'."\n";
2540  $out .= '<td class="center">'.$file['md5'].'</td>'."\n";
2541  $size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']);
2542  $totalsize += $size;
2543  $out .= '<td class="right">'.dol_print_size($size).'</td>'."\n";
2544  $out .= '<td class="right">'.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']), 'dayhour').'</td>'."\n";
2545  $out .= "</tr>\n";
2546  }
2547  $out .= '<tr class="liste_total">';
2548  $out .= '<td></td>'."\n";
2549  $out .= '<td>'.$langs->trans("Total").'</td>'."\n";
2550  $out .= '<td align="center"></td>'."\n";
2551  $out .= '<td align="center"></td>'."\n";
2552  $out .= '<td class="right">'.dol_print_size($totalsize).'</td>'."\n";
2553  $out .= '<td class="right"></td>'."\n";
2554  $out .= "</tr>\n";
2555  } else {
2556  $out .= '<tr class="oddeven"><td colspan="5" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
2557  }
2558  $out .= '</table>';
2559  $out .= '</div>';
2560 
2561  $out .= '<br>';
2562 
2563  // Files added
2564  $out .= load_fiche_titre($langs->trans("FilesAdded"));
2565 
2566  $totalsize = 0;
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 .= '<td class="center">'.$langs->trans("CurrentChecksum").'</td>';
2574  $out .= '<td class="right">'.$langs->trans("Size").'</td>';
2575  $out .= '<td class="right">'.$langs->trans("DateModification").'</td>';
2576  $out .= '</tr>'."\n";
2577  $tmpfilelist3 = dol_sort_array($file_list['added'], 'filename');
2578  if (is_array($tmpfilelist3) && count($tmpfilelist3)) {
2579  $i = 0;
2580  foreach ($tmpfilelist3 as $file) {
2581  $i++;
2582  $out .= '<tr class="oddeven">';
2583  $out .= '<td>'.$i.'</td>'."\n";
2584  $out .= '<td>'.dol_escape_htmltag($file['filename']).'</td>'."\n";
2585  $out .= '<td class="center">'.$file['expectedmd5'].'</td>'."\n";
2586  $out .= '<td class="center">'.$file['md5'].'</td>'."\n";
2587  $size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']);
2588  $totalsize += $size;
2589  $out .= '<td class="right">'.dol_print_size($size).'</td>'."\n";
2590  $out .= '<td class="right">'.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']), 'dayhour').'</td>'."\n";
2591  $out .= "</tr>\n";
2592  }
2593  $out .= '<tr class="liste_total">';
2594  $out .= '<td></td>'."\n";
2595  $out .= '<td>'.$langs->trans("Total").'</td>'."\n";
2596  $out .= '<td align="center"></td>'."\n";
2597  $out .= '<td align="center"></td>'."\n";
2598  $out .= '<td class="right">'.dol_print_size($totalsize).'</td>'."\n";
2599  $out .= '<td class="right"></td>'."\n";
2600  $out .= "</tr>\n";
2601  } else {
2602  $out .= '<tr class="oddeven"><td colspan="5" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
2603  }
2604  $out .= '</table>';
2605  $out .= '</div>';
2606 
2607 
2608  // Show warning
2609  if (empty($tmpfilelist) && empty($tmpfilelist2) && empty($tmpfilelist3)) {
2610  //setEventMessages($langs->trans("FileIntegrityIsStrictlyConformedWithReference"), null, 'mesgs');
2611  } else {
2612  //setEventMessages($langs->trans("FileIntegritySomeFilesWereRemovedOrModified"), null, 'warnings');
2613  }
2614  } else {
2615  throw new RestException(500, 'Error: Failed to found dolibarr_htdocs_dir into XML file '.$xmlfile);
2616  }
2617 
2618 
2619  // Scan scripts
2620  asort($checksumconcat); // Sort list of checksum
2621  $checksumget = md5(implode(',', $checksumconcat));
2622  $checksumtoget = trim((string) $xml->dolibarr_htdocs_dir_checksum);
2623 
2624  $outexpectedchecksum = ($checksumtoget ? $checksumtoget : $langs->trans("Unknown"));
2625  if ($checksumget == $checksumtoget) {
2626  if (count($file_list['added'])) {
2627  $resultcode = 'warning';
2628  $resultcomment = 'FileIntegrityIsOkButFilesWereAdded';
2629  //$outcurrentchecksum = $checksumget.' - <span class="'.$resultcode.'">'.$langs->trans("FileIntegrityIsOkButFilesWereAdded").'</span>';
2630  $outcurrentchecksum = $checksumget;
2631  } else {
2632  $resultcode = 'ok';
2633  $resultcomment = 'Success';
2634  //$outcurrentchecksum = '<span class="'.$resultcode.'">'.$checksumget.'</span>';
2635  $outcurrentchecksum = $checksumget;
2636  }
2637  } else {
2638  $resultcode = 'error';
2639  $resultcomment = 'Error';
2640  //$outcurrentchecksum = '<span class="'.$resultcode.'">'.$checksumget.'</span>';
2641  $outcurrentchecksum = $checksumget;
2642  }
2643  } else {
2644  throw new RestException(404, 'No signature file known');
2645  }
2646 
2647  return array('resultcode'=>$resultcode, 'resultcomment'=>$resultcomment, 'expectedchecksum'=> $outexpectedchecksum, 'currentchecksum'=> $outcurrentchecksum, 'out'=>$out);
2648  }
2649 
2650 
2660  public function getModules()
2661  {
2662  global $conf;
2663 
2664  if (!DolibarrApiAccess::$user->admin
2665  && (!getDolGlobalString('API_LOGINS_ALLOWED_FOR_GET_MODULES') || DolibarrApiAccess::$user->login != $conf->global->API_LOGINS_ALLOWED_FOR_GET_MODULES)) {
2666  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');
2667  }
2668 
2669  sort($conf->modules);
2670 
2671  return $this->_cleanObjectDatas($conf->modules);
2672  }
2673 }
if($user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition: card.php:58
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.
Definition: api.class.php:397
_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.
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.
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:745
getFilesUpdated(&$file_list, SimpleXMLElement $dir, $path='', $pathref='', &$checksumconcat=array())
Function to get list of updated or modified files.
Definition: files.lib.php:3574
dol_filemtime($pathoffile)
Return time of a file.
Definition: files.lib.php:647
dol_filesize($pathoffile)
Return size of a file.
Definition: files.lib.php:635
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:519
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 dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
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).
Definition: geturl.lib.php:42