dolibarr 23.0.3
api_objectlinks.class.php
1<?php
2/* Copyright (C) 2025 Jon Bendtsen <jon.bendtsen.github@jonb.dk>
3 * Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
4 * Copyright (C) 2025 Frédéric France <frederic.france@free.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
20use Luracast\Restler\RestException;
21
22require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php';
23require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
24require_once DOL_DOCUMENT_ROOT.'/core/class/objectlink.class.php';
25
26
34{
38 public static $FIELDS = array(
39 'fk_source',
40 'sourcetype',
41 'fk_target',
42 'targettype'
43 );
44
48 public $objectlink;
49
53 private $notrigger;
54
58 public function __construct()
59 {
60 global $db;
61 $this->db = $db;
62 $this->objectlink = new ObjectLink($this->db);
63 }
64
81 public function getById($id)
82 {
83 return $this->_fetch($id);
84 }
85
86
87
95 private function _setObjectLinkField($field, $value)
96 {
97
98 $clean_field = $this->_checkValForAPI($field, $value, $this->objectlink);
99
103 $intFields = array(
104 'fk_source',
105 'fk_target'
106 );
107
108 if (in_array($field, $intFields)) {
109 $this->objectlink->$field = (int) $clean_field;
110 } else {
111 $this->objectlink->$field = (string) $clean_field;
112 }
113 }
114
115
137 public function create($request_data = null)
138 {
139 // Check mandatory fields
140 $result = $this->_validate($request_data);
141
142 foreach ($request_data as $field => $value) {
143 if ($field == 'notrigger') {
144 $this->notrigger = (int) $value;
145 } else {
146 $this->_setObjectLinkField($field, $value);
147 }
148 }
149
150 // Permission check
151 $srctype = $this->objectlink->sourcetype;
152 if ($this->objectlink->sourcetype == 'subscription') {
153 $srctype = 'adherent';
154 }
155 $tgttype = $this->objectlink->targettype;
156 if ($this->objectlink->targettype == 'subscription') {
157 $tgttype = 'adherent';
158 }
159 if (!DolibarrApiAccess::$user->hasRight((string) $srctype, 'creer') && !DolibarrApiAccess::$user->hasRight((string) $srctype, 'write')) {
160 throw new RestException(403, 'denied access to create the objectlinks sourcetype='.$this->objectlink->sourcetype);
161 }
162 if (!DolibarrApiAccess::$user->hasRight((string) $tgttype, 'creer') && !DolibarrApiAccess::$user->hasRight((string) $tgttype, 'write')) {
163 throw new RestException(403, 'denied access to create the objectlinks targettype='.$this->objectlink->targettype);
164 }
165
166 $result = $this->objectlink->create(DolibarrApiAccess::$user, $this->objectlink->fk_source, $this->objectlink->sourcetype, $this->objectlink->fk_target, $this->objectlink->targettype, $this->objectlink->relationtype, $this->notrigger);
167
168 if ($result < 0) {
169 throw new RestException(500, 'when create objectlink : '.$this->objectlink->error);
170 }
171
172 if ($result == 0) {
173 throw new RestException(304, 'Object link already exists');
174 }
175
176 return array(
177 'success' => array(
178 'code' => 200,
179 'message' => 'object link created'
180 )
181 );
182 }
183
198 public function deleteById($id)
199 {
200 // Reverse permission check. First we find out which kind of objects are linked, and if the user has rights to that then we delete it.
201 $result = $this->objectlink->fetch($id);
202 if ($result) {
203 $srctype = $this->objectlink->sourcetype;
204 if ($this->objectlink->sourcetype == 'subscription') {
205 $srctype = 'adherent';
206 }
207 $tgttype = $this->objectlink->targettype;
208 if ($this->objectlink->targettype == 'subscription') {
209 $tgttype = 'adherent';
210 }
211 if (!DolibarrApiAccess::$user->hasRight(((string) $srctype), 'lire') && !DolibarrApiAccess::$user->hasRight(((string) $srctype), 'read')) {
212 throw new RestException(403, 'denied access to the objectlinks sourcetype');
213 }
214 if (!DolibarrApiAccess::$user->hasRight(((string) $tgttype), 'lire') && !DolibarrApiAccess::$user->hasRight(((string) $tgttype), 'read')) {
215 throw new RestException(403, 'denied access to the objectlinks targettype');
216 }
217 } else {
218 throw new RestException(404, 'Object Link not found');
219 }
220
221 if (!$this->objectlink->delete(DolibarrApiAccess::$user)) {
222 throw new RestException(500, 'Error when delete objectlink : '.$this->objectlink->error);
223 }
224
225 return array(
226 'success' => array(
227 'code' => 200,
228 'message' => 'object link deleted'
229 )
230 );
231 }
232
251 public function getByValues($fk_source, $sourcetype, $fk_target, $targettype, $relationtype = null)
252 {
253 $request_data = array(
254 'fk_source' => ((int) $fk_source),
255 'sourcetype' => (string) $sourcetype,
256 'fk_target' => ((int) $fk_target),
257 'targettype' => (string) $targettype,
258 'relationtype' => $relationtype,
259 );
260
261 // Check mandatory fields
262 $result = $this->_validate($request_data);
263
264 foreach ($request_data as $field => $value) {
265 $this->_setObjectLinkField($field, $value);
266 }
267
268 // Permission check
269 $srctype = $this->objectlink->sourcetype;
270 if ($this->objectlink->sourcetype == 'subscription') {
271 $srctype = 'adherent';
272 }
273 $tgttype = $this->objectlink->targettype;
274 if ($this->objectlink->targettype == 'subscription') {
275 $tgttype = 'adherent';
276 }
277 if (!DolibarrApiAccess::$user->hasRight((string) $srctype, 'creer') && !DolibarrApiAccess::$user->hasRight((string) $srctype, 'write')) {
278 throw new RestException(403, 'denied access to get the objectlinks sourcetype='.$this->objectlink->sourcetype);
279 }
280 if (!DolibarrApiAccess::$user->hasRight((string) $tgttype, 'creer') && !DolibarrApiAccess::$user->hasRight((string) $tgttype, 'write')) {
281 throw new RestException(403, 'denied access to get the objectlinks targettype='.$this->objectlink->targettype);
282 }
283
284 $findresult = $this->objectlink->fetchByValues($this->objectlink->fk_source, $this->objectlink->sourcetype, $this->objectlink->fk_target, $this->objectlink->targettype, $this->objectlink->relationtype);
285
286 if ($findresult < 0) {
287 throw new RestException(500, 'Error when finding objectlink : '.$this->objectlink->error);
288 } elseif ($findresult > 0) {
289 return $this->_cleanObjectDatas($this->objectlink);
290 } else {
291 throw new RestException(404, 'Object Link not found');
292 }
293 }
294
295
315 public function deleteByValues($fk_source, $sourcetype, $fk_target, $targettype, $relationtype = null, $notrigger = 0)
316 {
317 $request_data = array(
318 'fk_source' => ((int) $fk_source),
319 'sourcetype' => (string) $sourcetype,
320 'fk_target' => ((int) $fk_target),
321 'targettype' => (string) $targettype,
322 'relationtype' => $relationtype,
323 );
324
325 // Check mandatory fields
326 $result = $this->_validate($request_data);
327
328 foreach ($request_data as $field => $value) {
329 $this->_setObjectLinkField($field, $value);
330 }
331
332 // Permission check
333 $srctype = $this->objectlink->sourcetype;
334 if ($this->objectlink->sourcetype == 'subscription') {
335 $srctype = 'adherent';
336 }
337 $tgttype = $this->objectlink->targettype;
338 if ($this->objectlink->targettype == 'subscription') {
339 $tgttype = 'adherent';
340 }
341 if (!DolibarrApiAccess::$user->hasRight((string) $srctype, 'creer') && !DolibarrApiAccess::$user->hasRight((string) $srctype, 'write')) {
342 throw new RestException(403, 'denied access to delete the objectlinks sourcetype='.$this->objectlink->sourcetype);
343 }
344 if (!DolibarrApiAccess::$user->hasRight((string) $tgttype, 'creer') && !DolibarrApiAccess::$user->hasRight((string) $tgttype, 'write')) {
345 throw new RestException(403, 'denied access to delete the objectlinks targettype='.$this->objectlink->targettype);
346 }
347
348 $findresult = $this->objectlink->fetchByValues($this->objectlink->fk_source, $this->objectlink->sourcetype, $this->objectlink->fk_target, $this->objectlink->targettype, $this->objectlink->relationtype);
349
350 if ($findresult < 0) {
351 throw new RestException(500, 'Error when finding objectlink : '.$this->objectlink->error);
352 } elseif ($findresult > 0) {
353 $result = $this->objectlink->delete(DolibarrApiAccess::$user, $notrigger);
354
355 if ($result < 0) {
356 throw new RestException(500, 'Error when delete objectlink : '.$this->objectlink->error);
357 }
358
359 return array(
360 'success' => array(
361 'code' => 200,
362 'message' => 'object link deleted'
363 )
364 );
365 } else {
366 throw new RestException(404, 'Object Link not found');
367 }
368 }
369
383 private function _fetch($id)
384 {
385 $result = $this->objectlink->fetch($id);
386 if ($result) {
387 $srctype = $this->objectlink->sourcetype;
388 if ($this->objectlink->sourcetype == 'subscription') {
389 $srctype = 'adherent';
390 }
391 $tgttype = $this->objectlink->targettype;
392 if ($this->objectlink->targettype == 'subscription') {
393 $tgttype = 'adherent';
394 }
395 if (!DolibarrApiAccess::$user->hasRight(((string) $srctype), 'lire') && !DolibarrApiAccess::$user->hasRight(((string) $srctype), 'read')) {
396 throw new RestException(403, 'denied access to the objectlinks sourcetype');
397 }
398 if (!DolibarrApiAccess::$user->hasRight(((string) $tgttype), 'lire') && !DolibarrApiAccess::$user->hasRight(((string) $tgttype), 'read')) {
399 throw new RestException(403, 'denied access to the objectlinks targettype');
400 }
401 } else {
402 throw new RestException(404, 'Object Link not found');
403 }
404
405 return $this->_cleanObjectDatas($this->objectlink);
406 }
407
408 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
421 protected function _cleanObjectDatas($object)
422 {
423 // phpcs:enable
424 $object = parent::_cleanObjectDatas($object);
425
426 unset($object->module);
427 unset($object->entity);
428 unset($object->import_key);
429 unset($object->array_languages);
430 unset($object->contacts_ids);
431 unset($object->linkedObjectsIds);
432 unset($object->canvas);
433 unset($object->fk_project);
434 unset($object->contact_id);
435 unset($object->user);
436 unset($object->origin_type);
437 unset($object->origin_id);
438 unset($object->ref);
439 unset($object->ref_ext);
440 unset($object->statut);
441 unset($object->status);
442 unset($object->country_id);
443 unset($object->country_code);
444 unset($object->state_id);
445 unset($object->region_id);
446 unset($object->barcode_type);
447 unset($object->barcode_type_coder);
448 unset($object->mode_reglement_id);
449 unset($object->cond_reglement_id);
450 unset($object->demand_reason_id);
451 unset($object->transport_mode_id);
452 unset($object->shipping_method_id);
453 unset($object->shipping_method);
454 unset($object->fk_multicurrency);
455 unset($object->multicurrency_code);
456 unset($object->multicurrency_tx);
457 unset($object->multicurrency_total_ht);
458 unset($object->multicurrency_total_tva);
459 unset($object->multicurrency_total_ttc);
460 unset($object->multicurrency_total_localtax1);
461 unset($object->multicurrency_total_localtax2);
462 unset($object->last_main_doc);
463 unset($object->fk_account);
464 unset($object->note_public);
465 unset($object->note_private);
466 unset($object->total_ht);
467 unset($object->total_tva);
468 unset($object->total_localtax1);
469 unset($object->total_localtax2);
470 unset($object->total_ttc);
471 unset($object->lines);
472 unset($object->actiontypecode);
473 unset($object->name);
474 unset($object->lastname);
475 unset($object->firstname);
476 unset($object->civility_id);
477 unset($object->date_creation);
478 unset($object->date_validation);
479 unset($object->date_modification);
480 unset($object->tms);
481 unset($object->date_cloture);
482 unset($object->user_creation_id);
483 unset($object->user_validation_id);
484 unset($object->user_closing_id);
485 unset($object->user_modification_id);
486 unset($object->fk_user_creat);
487 unset($object->fk_user_modif);
488 unset($object->totalpaid);
489 unset($object->totalcreditnotes);
490 unset($object->totaldeposits);
491 unset($object->totalpaid_multicurrency);
492 unset($object->totalcreditnotes_multicurrency);
493 unset($object->totaldeposits_multicurrency);
494 unset($object->product);
495 unset($object->cond_reglement_supplier_id);
496 unset($object->deposit_percent);
497 unset($object->retained_warranty_fk_cond_reglement);
498 unset($object->warehouse_id);
499 unset($object->target);
500 unset($object->array_options);
501 unset($object->extraparams);
502 unset($object->specimen);
503
504 return $object;
505 }
506
507 // source before modifications was api_orders.class.php
517 private function _validate($data)
518 {
519 $objectlink = array();
520 foreach (ObjectLinks::$FIELDS as $field) {
521 if (!isset($data[$field])) {
522 throw new RestException(400, $field." field missing");
523 }
524 $objectlink[$field] = $data[$field];
525 }
526 return $objectlink;
527 }
528}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
Class for API REST v1.
Definition api.class.php:33
_checkValForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
Definition api.class.php:98