dolibarr  19.0.0-dev
api.class.php
1 <?php
2 /* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
3  * Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2020 Frédéric France <frederic.france@netlogic.fr>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 use Luracast\Restler\Restler;
21 use Luracast\Restler\RestException;
22 use Luracast\Restler\Defaults;
23 use Luracast\Restler\Format\UploadFormat;
24 
25 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
26 
31 {
32 
36  protected $db;
37 
41  public $r;
42 
50  public function __construct($db, $cachedir = '', $refreshCache = false)
51  {
52  global $conf, $dolibarr_main_url_root;
53 
54  if (empty($cachedir)) {
55  $cachedir = $conf->api->dir_temp;
56  }
57  Defaults::$cacheDirectory = $cachedir;
58 
59  $this->db = $db;
60  $production_mode = (empty($conf->global->API_PRODUCTION_MODE) ? false : true);
61  $this->r = new Restler($production_mode, $refreshCache);
62 
63  $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
64  $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
65 
66  $urlwithouturlrootautodetect = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim(DOL_MAIN_URL_ROOT));
67  $urlwithrootautodetect = $urlwithouturlroot.DOL_URL_ROOT; // This is to use local domain autodetected by dolibarr from url
68 
69  $this->r->setBaseUrls($urlwithouturlroot, $urlwithouturlrootautodetect);
70  $this->r->setAPIVersion(1);
71  //$this->r->setSupportedFormats('json');
72  //$this->r->setSupportedFormats('jsonFormat');
73  }
74 
75  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
86  protected function _checkValForAPI($field, $value, $object)
87  {
88  // phpcs:enable
89  // TODO Use type detected in $object->fields
90  if (in_array($field, array('note', 'note_private', 'note_public', 'desc', 'description'))) {
91  return sanitizeVal($value, 'restricthtml');
92  } else {
93  return sanitizeVal($value, 'alphanohtml');
94  }
95  }
96 
97  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
104  protected function _cleanObjectDatas($object)
105  {
106  // phpcs:enable
107  // Remove $db object property for object
108  unset($object->db);
109  unset($object->isextrafieldmanaged);
110  unset($object->ismultientitymanaged);
111  unset($object->restrictiononfksoc);
112  unset($object->table_rowid);
113  unset($object->pass);
114  unset($object->pass_indatabase);
115 
116  // Remove linkedObjects. We should already have and keep only linkedObjectsIds that avoid huge responses
117  unset($object->linkedObjects);
118  //unset($object->lines[$i]->linked_objects); // This is the array to create linked object during create
119 
120  unset($object->fields);
121  unset($object->oldline);
122 
123  unset($object->error);
124  unset($object->errors);
125  unset($object->errorhidden);
126 
127  unset($object->ref_previous);
128  unset($object->ref_next);
129  unset($object->imgWidth);
130  unset($object->imgHeight);
131  unset($object->barcode_type_code);
132  unset($object->barcode_type_label);
133 
134  unset($object->mode_reglement); // We use mode_reglement_id now
135  unset($object->cond_reglement); // We use cond_reglement_id now
136  unset($object->note); // We use note_public or note_private now
137  unset($object->contact); // We use contact_id now
138  unset($object->thirdparty); // We use thirdparty_id or fk_soc or socid now
139 
140  unset($object->projet); // Should be fk_project
141  unset($object->project); // Should be fk_project
142  unset($object->fk_projet); // Should be fk_project
143  unset($object->author); // Should be fk_user_author
144  unset($object->timespent_old_duration);
145  unset($object->timespent_id);
146  unset($object->timespent_duration);
147  unset($object->timespent_date);
148  unset($object->timespent_datehour);
149  unset($object->timespent_withhour);
150  unset($object->timespent_fk_user);
151  unset($object->timespent_note);
152  unset($object->fk_delivery_address);
153  unset($object->modelpdf);
154  unset($object->sendtoid);
155  unset($object->name_bis);
156  unset($object->newref);
157  unset($object->alreadypaid);
158  unset($object->openid);
159 
160  unset($object->statuts);
161  unset($object->statuts_short);
162  unset($object->statuts_logo);
163  unset($object->statuts_long);
164 
165  //unset($object->labelStatus);
166  //unset($object->labelStatusShort);
167 
168  unset($object->stats_propale);
169  unset($object->stats_commande);
170  unset($object->stats_contrat);
171  unset($object->stats_facture);
172  unset($object->stats_commande_fournisseur);
173  unset($object->stats_reception);
174  unset($object->stats_mrptoconsume);
175  unset($object->stats_mrptoproduce);
176 
177  unset($object->element);
178  unset($object->element_for_permission);
179  unset($object->fk_element);
180  unset($object->table_element);
181  unset($object->table_element_line);
182  unset($object->class_element_line);
183  unset($object->picto);
184 
185  unset($object->fieldsforcombobox);
186  unset($object->regeximgext);
187 
188  unset($object->skip_update_total);
189  unset($object->context);
190  unset($object->next_prev_filter);
191 
192  unset($object->region);
193  unset($object->region_code);
194  unset($object->country);
195  unset($object->state);
196  unset($object->state_code);
197  unset($object->departement);
198  unset($object->departement_code);
199 
200  unset($object->libelle_statut);
201  unset($object->libelle_paiement);
202 
203  unset($object->prefix_comm);
204 
205  if (!isset($object->table_element) || $object->table_element != 'ticket') {
206  unset($object->comments);
207  }
208 
209  // Remove the $oldcopy property because it is not supported by the JSON
210  // encoder. The following error is generated when trying to serialize
211  // it: "Error encoding/decoding JSON: Type is not supported"
212  // Note: Event if this property was correctly handled by the JSON
213  // encoder, it should be ignored because keeping it would let the API
214  // have a very strange behavior: calling PUT and then GET on the same
215  // resource would give different results:
216  // PUT /objects/{id} -> returns object with oldcopy = previous version of the object
217  // GET /objects/{id} -> returns object with oldcopy empty
218  unset($object->oldcopy);
219 
220  // If object has lines, remove $db property
221  if (isset($object->lines) && is_array($object->lines) && count($object->lines) > 0) {
222  $nboflines = count($object->lines);
223  for ($i = 0; $i < $nboflines; $i++) {
224  $this->_cleanObjectDatas($object->lines[$i]);
225 
226  unset($object->lines[$i]->contact);
227  unset($object->lines[$i]->contact_id);
228  unset($object->lines[$i]->country);
229  unset($object->lines[$i]->country_id);
230  unset($object->lines[$i]->country_code);
231  unset($object->lines[$i]->mode_reglement_id);
232  unset($object->lines[$i]->mode_reglement_code);
233  unset($object->lines[$i]->mode_reglement);
234  unset($object->lines[$i]->cond_reglement_id);
235  unset($object->lines[$i]->cond_reglement_code);
236  unset($object->lines[$i]->cond_reglement);
237  unset($object->lines[$i]->fk_delivery_address);
238  unset($object->lines[$i]->fk_projet);
239  unset($object->lines[$i]->fk_project);
240  unset($object->lines[$i]->thirdparty);
241  unset($object->lines[$i]->user);
242  unset($object->lines[$i]->model_pdf);
243  unset($object->lines[$i]->modelpdf);
244  unset($object->lines[$i]->note_public);
245  unset($object->lines[$i]->note_private);
246  unset($object->lines[$i]->fk_incoterms);
247  unset($object->lines[$i]->label_incoterms);
248  unset($object->lines[$i]->location_incoterms);
249  unset($object->lines[$i]->name);
250  unset($object->lines[$i]->lastname);
251  unset($object->lines[$i]->firstname);
252  unset($object->lines[$i]->civility_id);
253  unset($object->lines[$i]->fk_multicurrency);
254  unset($object->lines[$i]->multicurrency_code);
255  unset($object->lines[$i]->shipping_method_id);
256  }
257  }
258 
259  if (!empty($object->thirdparty) && is_object($object->thirdparty)) {
260  $this->_cleanObjectDatas($object->thirdparty);
261  }
262 
263  if (!empty($object->product) && is_object($object->product)) {
264  $this->_cleanObjectDatas($object->product);
265  }
266 
267  return $object;
268  }
269 
270  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
282  protected static function _checkAccessToResource($resource, $resource_id = 0, $dbtablename = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid')
283  {
284  // phpcs:enable
285  // Features/modules to check
286  $featuresarray = array($resource);
287  if (preg_match('/&/', $resource)) {
288  $featuresarray = explode("&", $resource);
289  } elseif (preg_match('/\|/', $resource)) {
290  $featuresarray = explode("|", $resource);
291  }
292 
293  // More subfeatures to check
294  if (!empty($feature2)) {
295  $feature2 = explode("|", $feature2);
296  }
297 
298  return checkUserAccessToObject(DolibarrApiAccess::$user, $featuresarray, $resource_id, $dbtablename, $feature2, $dbt_keyfield, $dbt_select);
299  }
300 
301  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
310  protected function _checkFilters($sqlfilters, &$error = '')
311  {
312  // phpcs:enable
313 
314  return dolCheckFilters($sqlfilters, $error);
315  }
316 
317  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
318  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
328  protected static function _forge_criteria_callback($matches)
329  {
330  return dolForgeCriteriaCallback($matches);
331  }
332 }
Class for API REST v1.
Definition: api.class.php:31
__construct($db, $cachedir='', $refreshCache=false)
Constructor.
Definition: api.class.php:50
static _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid')
Check access by user to a given resource.
Definition: api.class.php:282
_checkFilters($sqlfilters, &$error='')
Return if a $sqlfilters parameter is valid Function no more used.
Definition: api.class.php:310
_checkValForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
Definition: api.class.php:86
_cleanObjectDatas($object)
Clean sensible object datas.
Definition: api.class.php:104
static _forge_criteria_callback($matches)
Function to forge a SQL criteria from a Generic filter string.
Definition: api.class.php:328
dolCheckFilters($sqlfilters, &$error='')
Return if a $sqlfilters parameter has a valid balance of parenthesis.
dolForgeCriteriaCallback($matches)
Function to forge a SQL criteria from a Dolibarr filter syntax string.
sanitizeVal($out='', $check='alphanohtml', $filter=null, $options=null)
Return a sanitized or empty value after checking value against a rule.
checkUserAccessToObject($user, array $featuresarray, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='', $dbt_select='rowid', $parenttableforentity='')
Check that access by a given user to an object is ok.