dolibarr 25.0.0-alpha
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 $clean_field = $this->_checkValForAPI($field, $value, $this->objectlink);
98
102 $intFields = array(
103 'fk_source',
104 'fk_target'
105 );
106
107 if (in_array($field, $intFields)) {
108 $this->objectlink->$field = (int) $clean_field; // Clean by _checkValForAPI previously
109 } else {
110 $this->objectlink->$field = (string) $clean_field; // Clean by _checkValForAPI previously
111 }
112 }
113
114
136 public function create($request_data = null)
137 {
138 // Check mandatory fields
139 $result = $this->_validate($request_data);
140
141 foreach ($request_data as $field => $value) {
142 if ($field == 'notrigger') {
143 $this->notrigger = (int) $value;
144 } else {
145 $this->_setObjectLinkField($field, $value);
146 }
147 }
148
149 // Permission check
150 $srctype = $this->objectlink->sourcetype;
151 if ($this->objectlink->sourcetype == 'subscription') {
152 $srctype = 'adherent';
153 }
154 if ($this->objectlink->sourcetype == 'conferenceorboothattendee') {
155 $srctype = 'projet';
156 }
157 $tgttype = $this->objectlink->targettype;
158 if ($this->objectlink->targettype == 'subscription') {
159 $tgttype = 'adherent';
160 }
161 if ($this->objectlink->targettype == 'conferenceorboothattendee') {
162 $tgttype = 'projet';
163 }
164 if (!DolibarrApiAccess::$user->hasRight((string) $srctype, 'creer') && !DolibarrApiAccess::$user->hasRight((string) $srctype, 'write')) {
165 throw new RestException(403, 'denied access to create the objectlinks sourcetype='.$this->objectlink->sourcetype);
166 }
167 if (!DolibarrApiAccess::$user->hasRight((string) $tgttype, 'creer') && !DolibarrApiAccess::$user->hasRight((string) $tgttype, 'write')) {
168 throw new RestException(403, 'denied access to create the objectlinks targettype='.$this->objectlink->targettype);
169 }
170 if (!checkUserAccessToObject(DolibarrApiAccess::$user, array($srctype), $this->objectlink->fk_source)) {
171 throw new RestException(403, 'denied access to create the objectlinks sourcetype='.$this->objectlink->sourcetype);
172 }
173 if (!checkUserAccessToObject(DolibarrApiAccess::$user, array($tgttype), $this->objectlink->fk_target)) {
174 throw new RestException(403, 'denied access to create the objectlinks targettype='.$this->objectlink->targettype);
175 }
176
177 // Create object link (in database)
178 $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);
179
180 if ($result < 0) {
181 throw new RestException(500, 'when create objectlink : '.$this->objectlink->error);
182 }
183
184 if ($result == 0) {
185 throw new RestException(304, 'Object link already exists');
186 }
187
188 return array(
189 'success' => array(
190 'code' => 200,
191 'message' => 'object link created'
192 )
193 );
194 }
195
210 public function deleteById($id)
211 {
212 // 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.
213 $result = $this->objectlink->fetch($id);
214 if ($result) {
215 $srctype = $this->objectlink->sourcetype;
216 if ($this->objectlink->sourcetype == 'subscription') {
217 $srctype = 'adherent';
218 }
219 if ($this->objectlink->sourcetype == 'conferenceorboothattendee') {
220 $srctype = 'projet';
221 }
222 $tgttype = $this->objectlink->targettype;
223 if ($this->objectlink->targettype == 'subscription') {
224 $tgttype = 'adherent';
225 }
226 if ($this->objectlink->targettype == 'conferenceorboothattendee') {
227 $tgttype = 'projet';
228 }
229 if (!DolibarrApiAccess::$user->hasRight(((string) $srctype), 'creer') && !DolibarrApiAccess::$user->hasRight(((string) $srctype), 'write')) {
230 throw new RestException(403, 'denied access to the objectlinks sourcetype');
231 }
232 if (!DolibarrApiAccess::$user->hasRight(((string) $tgttype), 'creer') && !DolibarrApiAccess::$user->hasRight(((string) $tgttype), 'write')) {
233 throw new RestException(403, 'denied access to the objectlinks targettype');
234 }
235 if (!checkUserAccessToObject(DolibarrApiAccess::$user, array($srctype), $this->objectlink->fk_source)) {
236 throw new RestException(403, 'denied access to the objectlinks sourcetype');
237 }
238 if (!checkUserAccessToObject(DolibarrApiAccess::$user, array($tgttype), $this->objectlink->fk_target)) {
239 throw new RestException(403, 'denied access to the objectlinks targettype');
240 }
241 } else {
242 throw new RestException(404, 'Object Link not found');
243 }
244
245 if (!$this->objectlink->delete(DolibarrApiAccess::$user)) {
246 throw new RestException(500, 'Error when delete objectlink : '.$this->objectlink->error);
247 }
248
249 return array(
250 'success' => array(
251 'code' => 200,
252 'message' => 'object link deleted'
253 )
254 );
255 }
256
275 public function getByValues($fk_source, $sourcetype, $fk_target, $targettype, $relationtype = null)
276 {
277 $request_data = array(
278 'fk_source' => ((int) $fk_source),
279 'sourcetype' => (string) $sourcetype,
280 'fk_target' => ((int) $fk_target),
281 'targettype' => (string) $targettype,
282 'relationtype' => $relationtype,
283 );
284
285 // Check mandatory fields
286 $result = $this->_validate($request_data);
287
288 foreach ($request_data as $field => $value) {
289 $this->_setObjectLinkField($field, $value);
290 }
291
292 // Permission check
293 $srctype = $this->objectlink->sourcetype;
294 if ($this->objectlink->sourcetype == 'subscription') {
295 $srctype = 'adherent';
296 }
297 if ($this->objectlink->sourcetype == 'conferenceorboothattendee') {
298 $srctype = 'projet';
299 }
300 $tgttype = $this->objectlink->targettype;
301 if ($this->objectlink->targettype == 'subscription') {
302 $tgttype = 'adherent';
303 }
304 if ($this->objectlink->targettype == 'conferenceorboothattendee') {
305 $tgttype = 'projet';
306 }
307 if (!DolibarrApiAccess::$user->hasRight((string) $srctype, 'creer') && !DolibarrApiAccess::$user->hasRight((string) $srctype, 'write')) {
308 throw new RestException(403, 'denied access to get the objectlinks sourcetype='.$this->objectlink->sourcetype);
309 }
310 if (!DolibarrApiAccess::$user->hasRight((string) $tgttype, 'creer') && !DolibarrApiAccess::$user->hasRight((string) $tgttype, 'write')) {
311 throw new RestException(403, 'denied access to get the objectlinks targettype='.$this->objectlink->targettype);
312 }
313 if (!checkUserAccessToObject(DolibarrApiAccess::$user, array($srctype), $this->objectlink->fk_source)) {
314 throw new RestException(403, 'denied access to the objectlinks sourcetype');
315 }
316 if (!checkUserAccessToObject(DolibarrApiAccess::$user, array($tgttype), $this->objectlink->fk_target)) {
317 throw new RestException(403, 'denied access to the objectlinks targettype');
318 }
319
320 $findresult = $this->objectlink->fetchByValues($this->objectlink->fk_source, $this->objectlink->sourcetype, $this->objectlink->fk_target, $this->objectlink->targettype, $this->objectlink->relationtype);
321
322 if ($findresult < 0) {
323 throw new RestException(500, 'Error when finding objectlink : '.$this->objectlink->error);
324 } elseif ($findresult > 0) {
325 return $this->_cleanObjectDatas($this->objectlink);
326 } else {
327 throw new RestException(404, 'Object Link not found');
328 }
329 }
330
331
351 public function deleteByValues($fk_source, $sourcetype, $fk_target, $targettype, $relationtype = null, $notrigger = 0)
352 {
353 $request_data = array(
354 'fk_source' => ((int) $fk_source),
355 'sourcetype' => (string) $sourcetype,
356 'fk_target' => ((int) $fk_target),
357 'targettype' => (string) $targettype,
358 'relationtype' => $relationtype,
359 );
360
361 // Check mandatory fields
362 $result = $this->_validate($request_data);
363
364 foreach ($request_data as $field => $value) {
365 $this->_setObjectLinkField($field, $value);
366 }
367
368 // Permission check
369 $srctype = $this->objectlink->sourcetype;
370 if ($this->objectlink->sourcetype == 'subscription') {
371 $srctype = 'adherent';
372 }
373 if ($this->objectlink->sourcetype == 'conferenceorboothattendee') {
374 $srctype = 'projet';
375 }
376 $tgttype = $this->objectlink->targettype;
377 if ($this->objectlink->targettype == 'subscription') {
378 $tgttype = 'adherent';
379 }
380 if ($this->objectlink->targettype == 'conferenceorboothattendee') {
381 $tgttype = 'projet';
382 }
383 if (!DolibarrApiAccess::$user->hasRight((string) $srctype, 'creer') && !DolibarrApiAccess::$user->hasRight((string) $srctype, 'write')) {
384 throw new RestException(403, 'denied access to delete the objectlinks sourcetype='.$this->objectlink->sourcetype);
385 }
386 if (!DolibarrApiAccess::$user->hasRight((string) $tgttype, 'creer') && !DolibarrApiAccess::$user->hasRight((string) $tgttype, 'write')) {
387 throw new RestException(403, 'denied access to delete the objectlinks targettype='.$this->objectlink->targettype);
388 }
389 if (!checkUserAccessToObject(DolibarrApiAccess::$user, array($srctype), $this->objectlink->fk_source)) {
390 throw new RestException(403, 'denied access to the objectlinks sourcetype');
391 }
392 if (!checkUserAccessToObject(DolibarrApiAccess::$user, array($tgttype), $this->objectlink->fk_target)) {
393 throw new RestException(403, 'denied access to the objectlinks targettype');
394 }
395
396 $findresult = $this->objectlink->fetchByValues($this->objectlink->fk_source, $this->objectlink->sourcetype, $this->objectlink->fk_target, $this->objectlink->targettype, $this->objectlink->relationtype);
397
398 if ($findresult < 0) {
399 throw new RestException(500, 'Error when finding objectlink : '.$this->objectlink->error);
400 } elseif ($findresult > 0) {
401 $result = $this->objectlink->delete(DolibarrApiAccess::$user, $notrigger);
402
403 if ($result < 0) {
404 throw new RestException(500, 'Error when delete objectlink : '.$this->objectlink->error);
405 }
406
407 return array(
408 'success' => array(
409 'code' => 200,
410 'message' => 'object link deleted'
411 )
412 );
413 } else {
414 throw new RestException(404, 'Object Link not found');
415 }
416 }
417
431 private function _fetch($id)
432 {
433 $result = $this->objectlink->fetch($id);
434 if ($result) {
435 $srctype = $this->objectlink->sourcetype;
436 if ($this->objectlink->sourcetype == 'subscription') {
437 $srctype = 'adherent';
438 }
439 if ($this->objectlink->sourcetype == 'conferenceorboothattendee') {
440 $srctype = 'projet';
441 }
442 $tgttype = $this->objectlink->targettype;
443 if ($this->objectlink->targettype == 'subscription') {
444 $tgttype = 'adherent';
445 }
446 if ($this->objectlink->targettype == 'conferenceorboothattendee') {
447 $tgttype = 'projet';
448 }
449 if (!DolibarrApiAccess::$user->hasRight(((string) $srctype), 'lire') && !DolibarrApiAccess::$user->hasRight(((string) $srctype), 'read')) {
450 throw new RestException(403, 'denied access to the objectlinks sourcetype');
451 }
452 if (!DolibarrApiAccess::$user->hasRight(((string) $tgttype), 'lire') && !DolibarrApiAccess::$user->hasRight(((string) $tgttype), 'read')) {
453 throw new RestException(403, 'denied access to the objectlinks targettype');
454 }
455 if (!checkUserAccessToObject(DolibarrApiAccess::$user, array($srctype), $this->objectlink->fk_source)) {
456 throw new RestException(403, 'denied access to the objectlinks sourcetype');
457 }
458 if (!checkUserAccessToObject(DolibarrApiAccess::$user, array($tgttype), $this->objectlink->fk_target)) {
459 throw new RestException(403, 'denied access to the objectlinks targettype');
460 }
461 } else {
462 throw new RestException(404, 'Object Link not found');
463 }
464
465 return $this->_cleanObjectDatas($this->objectlink);
466 }
467
468 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
481 protected function _cleanObjectDatas($object)
482 {
483 // phpcs:enable
484 $object = parent::_cleanObjectDatas($object);
485
486 unset($object->module);
487 unset($object->entity);
488 unset($object->import_key);
489 unset($object->array_languages);
490 unset($object->contacts_ids);
491 unset($object->linkedObjectsIds);
492 unset($object->canvas);
493 unset($object->fk_project);
494 unset($object->contact_id);
495 unset($object->user);
496 unset($object->origin_type);
497 unset($object->origin_id);
498 unset($object->ref);
499 unset($object->ref_ext);
500 unset($object->statut);
501 unset($object->status);
502 unset($object->country_id);
503 unset($object->country_code);
504 unset($object->state_id);
505 unset($object->region_id);
506 unset($object->barcode_type);
507 unset($object->barcode_type_coder);
508 unset($object->mode_reglement_id);
509 unset($object->cond_reglement_id);
510 unset($object->demand_reason_id);
511 unset($object->transport_mode_id);
512 unset($object->shipping_method_id);
513 unset($object->shipping_method);
514 unset($object->fk_multicurrency);
515 unset($object->multicurrency_code);
516 unset($object->multicurrency_tx);
517 unset($object->multicurrency_total_ht);
518 unset($object->multicurrency_total_tva);
519 unset($object->multicurrency_total_ttc);
520 unset($object->multicurrency_total_localtax1);
521 unset($object->multicurrency_total_localtax2);
522 unset($object->last_main_doc);
523 unset($object->fk_account);
524 unset($object->note_public);
525 unset($object->note_private);
526 unset($object->total_ht);
527 unset($object->total_tva);
528 unset($object->total_localtax1);
529 unset($object->total_localtax2);
530 unset($object->total_ttc);
531 unset($object->lines);
532 unset($object->actiontypecode);
533 unset($object->name);
534 unset($object->lastname);
535 unset($object->firstname);
536 unset($object->civility_id);
537 unset($object->date_creation);
538 unset($object->date_validation);
539 unset($object->date_modification);
540 unset($object->tms);
541 unset($object->date_cloture);
542 unset($object->user_creation_id);
543 unset($object->user_validation_id);
544 unset($object->user_closing_id);
545 unset($object->user_modification_id);
546 unset($object->fk_user_creat);
547 unset($object->fk_user_modif);
548 unset($object->totalpaid);
549 unset($object->totalcreditnotes);
550 unset($object->totaldeposits);
551 unset($object->totalpaid_multicurrency);
552 unset($object->totalcreditnotes_multicurrency);
553 unset($object->totaldeposits_multicurrency);
554 unset($object->product);
555 unset($object->cond_reglement_supplier_id);
556 unset($object->deposit_percent);
557 unset($object->retained_warranty_fk_cond_reglement);
558 unset($object->warehouse_id);
559 unset($object->target);
560 unset($object->array_options);
561 unset($object->extraparams);
562 unset($object->specimen);
563
564 return $object;
565 }
566
567 // source before modifications was api_orders.class.php
577 private function _validate($data)
578 {
579 $objectlink = array();
580 foreach (ObjectLinks::$FIELDS as $field) {
581 if (!isset($data[$field])) {
582 throw new RestException(400, $field." field missing");
583 }
584 $objectlink[$field] = $data[$field];
585 }
586 return $objectlink;
587 }
588}
$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:35
_checkValForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
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.