dolibarr 19.0.4
api_categories.class.php
1<?php
2/* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18use Luracast\Restler\RestException;
19
20require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
21require_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php';
22
23
24require_once DOL_DOCUMENT_ROOT.'/adherents/class/api_members.class.php';
25require_once DOL_DOCUMENT_ROOT.'/product/class/api_products.class.php';
26require_once DOL_DOCUMENT_ROOT.'/societe/class/api_contacts.class.php';
27require_once DOL_DOCUMENT_ROOT.'/societe/class/api_thirdparties.class.php';
28require_once DOL_DOCUMENT_ROOT.'/projet/class/api_projects.class.php';
29
37{
41 public static $FIELDS = array(
42 'label',
43 'type'
44 );
45
46 public static $TYPES = array(
47 0 => 'product',
48 1 => 'supplier',
49 2 => 'customer',
50 3 => 'member',
51 4 => 'contact',
52 5 => 'account',
53 6 => 'project',
54 7 => 'user',
55 8 => 'bank_line',
56 9 => 'warehouse',
57 10 => 'actioncomm',
58 11 => 'website_page',
59 12 => 'ticket',
60 13 => 'knowledgemanagement'
61 );
62
66 public $category;
67
71 public function __construct()
72 {
73 global $db, $conf;
74 $this->db = $db;
75 $this->category = new Categorie($this->db);
76 }
77
89 public function get($id, $include_childs = false)
90 {
91 if (!DolibarrApiAccess::$user->rights->categorie->lire) {
92 throw new RestException(401);
93 }
94
95 $result = $this->category->fetch($id);
96 if (!$result) {
97 throw new RestException(404, 'category not found');
98 }
99
100 if (!DolibarrApi::_checkAccessToResource('categorie', $this->category->id)) {
101 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
102 }
103
104 if ($include_childs) {
105 $cats = $this->category->get_filles();
106 if (!is_array($cats)) {
107 throw new RestException(500, 'Error when fetching child categories', array_merge(array($this->category->error), $this->category->errors));
108 }
109 $this->category->childs = array();
110 foreach ($cats as $cat) {
111 $this->category->childs[] = $this->_cleanObjectDatas($cat);
112 }
113 }
114
115 return $this->_cleanObjectDatas($this->category);
116 }
117
134 public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $sqlfilters = '', $properties = '')
135 {
136 global $db, $conf;
137
138 $obj_ret = array();
139
140 if (!DolibarrApiAccess::$user->rights->categorie->lire) {
141 throw new RestException(401);
142 }
143
144 $sql = "SELECT t.rowid";
145 $sql .= " FROM ".MAIN_DB_PREFIX."categorie AS t LEFT JOIN ".MAIN_DB_PREFIX."categories_extrafields AS ef ON (ef.fk_object = t.rowid)"; // Modification VMR Global Solutions to include extrafields as search parameters in the API GET call, so we will be able to filter on extrafields
146 $sql .= ' WHERE t.entity IN ('.getEntity('category').')';
147 if (!empty($type)) {
148 $sql .= ' AND t.type='.array_search($type, Categories::$TYPES);
149 }
150 // Add sql filters
151 if ($sqlfilters) {
152 $errormessage = '';
153 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
154 if ($errormessage) {
155 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
156 }
157 }
158
159 $sql .= $this->db->order($sortfield, $sortorder);
160 if ($limit) {
161 if ($page < 0) {
162 $page = 0;
163 }
164 $offset = $limit * $page;
165
166 $sql .= $this->db->plimit($limit + 1, $offset);
167 }
168
169 $result = $this->db->query($sql);
170 if ($result) {
171 $i = 0;
172 $num = $this->db->num_rows($result);
173 $min = min($num, ($limit <= 0 ? $num : $limit));
174 while ($i < $min) {
175 $obj = $this->db->fetch_object($result);
176 $category_static = new Categorie($this->db);
177 if ($category_static->fetch($obj->rowid)) {
178 $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($category_static), $properties);
179 }
180 $i++;
181 }
182 } else {
183 throw new RestException(503, 'Error when retrieve category list : '.$this->db->lasterror());
184 }
185
186 return $obj_ret;
187 }
188
195 public function post($request_data = null)
196 {
197 if (!DolibarrApiAccess::$user->rights->categorie->creer) {
198 throw new RestException(401);
199 }
200
201 // Check mandatory fields
202 $result = $this->_validate($request_data);
203
204 foreach ($request_data as $field => $value) {
205 if ($field === 'caller') {
206 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again whith the caller
207 $this->category->context['caller'] = $request_data['caller'];
208 continue;
209 }
210
211 $this->category->$field = $value;
212 }
213 if ($this->category->create(DolibarrApiAccess::$user) < 0) {
214 throw new RestException(500, 'Error when creating category', array_merge(array($this->category->error), $this->category->errors));
215 }
216 return $this->category->id;
217 }
218
226 public function put($id, $request_data = null)
227 {
228 if (!DolibarrApiAccess::$user->rights->categorie->creer) {
229 throw new RestException(401);
230 }
231
232 $result = $this->category->fetch($id);
233 if (!$result) {
234 throw new RestException(404, 'category not found');
235 }
236
237 if (!DolibarrApi::_checkAccessToResource('categorie', $this->category->id)) {
238 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
239 }
240
241 foreach ($request_data as $field => $value) {
242 if ($field == 'id') {
243 continue;
244 }
245 if ($field === 'caller') {
246 // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again whith the caller
247 $this->category->context['caller'] = $request_data['caller'];
248 continue;
249 }
250
251 if ($field == 'array_options' && is_array($value)) {
252 foreach ($value as $index => $val) {
253 $this->category->array_options[$index] = $this->_checkValForAPI($field, $val, $this->category);
254 }
255 continue;
256 }
257 $this->category->$field = $this->_checkValForAPI($field, $value, $this->category);
258 }
259
260 if ($this->category->update(DolibarrApiAccess::$user) > 0) {
261 return $this->get($id);
262 } else {
263 throw new RestException(500, $this->category->error);
264 }
265 }
266
273 public function delete($id)
274 {
275 if (!DolibarrApiAccess::$user->rights->categorie->supprimer) {
276 throw new RestException(401);
277 }
278 $result = $this->category->fetch($id);
279 if (!$result) {
280 throw new RestException(404, 'category not found');
281 }
282
283 if (!DolibarrApi::_checkAccessToResource('categorie', $this->category->id)) {
284 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
285 }
286
287 if ($this->category->delete(DolibarrApiAccess::$user) <= 0) {
288 throw new RestException(500, 'Error when delete category : ' . $this->category->error);
289 }
290
291 return array(
292 'success' => array(
293 'code' => 200,
294 'message' => 'Category deleted'
295 )
296 );
297 }
298
316 public function getListForObject($id, $type, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
317 {
318 if (!in_array($type, [
319 Categorie::TYPE_PRODUCT,
320 Categorie::TYPE_CONTACT,
321 Categorie::TYPE_CUSTOMER,
322 Categorie::TYPE_SUPPLIER,
323 Categorie::TYPE_MEMBER,
324 Categorie::TYPE_PROJECT,
325 Categorie::TYPE_KNOWLEDGEMANAGEMENT
326 ])) {
327 throw new RestException(401);
328 }
329
330 if ($type == Categorie::TYPE_PRODUCT && !(DolibarrApiAccess::$user->rights->produit->lire || DolibarrApiAccess::$user->rights->service->lire)) {
331 throw new RestException(401);
332 } elseif ($type == Categorie::TYPE_CONTACT && !DolibarrApiAccess::$user->rights->contact->lire) {
333 throw new RestException(401);
334 } elseif ($type == Categorie::TYPE_CUSTOMER && !DolibarrApiAccess::$user->hasRight('societe', 'lire')) {
335 throw new RestException(401);
336 } elseif ($type == Categorie::TYPE_SUPPLIER && !DolibarrApiAccess::$user->rights->fournisseur->lire) {
337 throw new RestException(401);
338 } elseif ($type == Categorie::TYPE_MEMBER && !DolibarrApiAccess::$user->rights->adherent->lire) {
339 throw new RestException(401);
340 } elseif ($type == Categorie::TYPE_PROJECT && !DolibarrApiAccess::$user->rights->projet->lire) {
341 throw new RestException(401);
342 } elseif ($type == Categorie::TYPE_KNOWLEDGEMANAGEMENT && !DolibarrApiAccess::$user->hasRight('knowledgemanagement', 'knowledgerecord', 'read')) {
343 throw new RestException(401);
344 }
345
346 $categories = $this->category->getListForItem($id, $type, $sortfield, $sortorder, $limit, $page);
347
348 if (!is_array($categories)) {
349 throw new RestException(600, 'Error when fetching object categories', array_merge(array($this->category->error), $this->category->errors));
350 }
351 return $categories;
352 }
353
366 public function linkObjectById($id, $type, $object_id)
367 {
368 if (empty($type) || empty($object_id)) {
369 throw new RestException(401);
370 }
371
372 if (!DolibarrApiAccess::$user->rights->categorie->lire) {
373 throw new RestException(401);
374 }
375
376 $result = $this->category->fetch($id);
377 if (!$result) {
378 throw new RestException(404, 'category not found');
379 }
380
381 if ($type === Categorie::TYPE_PRODUCT) {
382 if (!(DolibarrApiAccess::$user->rights->produit->creer || DolibarrApiAccess::$user->rights->service->creer)) {
383 throw new RestException(401);
384 }
385 $object = new Product($this->db);
386 } elseif ($type === Categorie::TYPE_CUSTOMER) {
387 if (!DolibarrApiAccess::$user->rights->societe->creer) {
388 throw new RestException(401);
389 }
390 $object = new Societe($this->db);
391 } elseif ($type === Categorie::TYPE_SUPPLIER) {
392 if (!DolibarrApiAccess::$user->rights->societe->creer) {
393 throw new RestException(401);
394 }
395 $object = new Societe($this->db);
396 } elseif ($type === Categorie::TYPE_CONTACT) {
397 if (!DolibarrApiAccess::$user->rights->societe->contact->creer) {
398 throw new RestException(401);
399 }
400 $object = new Contact($this->db);
401 } elseif ($type === Categorie::TYPE_MEMBER) {
402 if (!DolibarrApiAccess::$user->hasRight('adherent', 'creer')) {
403 throw new RestException(401);
404 }
405 $object = new Adherent($this->db);
406 } else {
407 throw new RestException(401, "this type is not recognized yet.");
408 }
409
410 if (!empty($object)) {
411 $result = $object->fetch($object_id);
412 if ($result > 0) {
413 $result = $this->category->add_type($object, $type);
414 if ($result < 0) {
415 if ($this->category->error != 'DB_ERROR_RECORD_ALREADY_EXISTS') {
416 throw new RestException(500, 'Error when linking object', array_merge(array($this->category->error), $this->category->errors));
417 }
418 }
419 } else {
420 throw new RestException(500, 'Error when fetching object', array_merge(array($object->error), $object->errors));
421 }
422
423 return array(
424 'success' => array(
425 'code' => 200,
426 'message' => 'Objects succefully linked to the category'
427 )
428 );
429 }
430
431 throw new RestException(401);
432 }
433
446 public function linkObjectByRef($id, $type, $object_ref)
447 {
448 if (empty($type) || empty($object_ref)) {
449 throw new RestException(401);
450 }
451
452 if (!DolibarrApiAccess::$user->rights->categorie->lire) {
453 throw new RestException(401);
454 }
455
456 $result = $this->category->fetch($id);
457 if (!$result) {
458 throw new RestException(404, 'category not found');
459 }
460
461 if ($type === Categorie::TYPE_PRODUCT) {
462 if (!(DolibarrApiAccess::$user->rights->produit->creer || DolibarrApiAccess::$user->rights->service->creer)) {
463 throw new RestException(401);
464 }
465 $object = new Product($this->db);
466 } elseif ($type === Categorie::TYPE_CUSTOMER) {
467 if (!DolibarrApiAccess::$user->rights->societe->creer) {
468 throw new RestException(401);
469 }
470 $object = new Societe($this->db);
471 } elseif ($type === Categorie::TYPE_SUPPLIER) {
472 if (!DolibarrApiAccess::$user->rights->societe->creer) {
473 throw new RestException(401);
474 }
475 $object = new Societe($this->db);
476 } elseif ($type === Categorie::TYPE_CONTACT) {
477 if (!DolibarrApiAccess::$user->rights->societe->contact->creer) {
478 throw new RestException(401);
479 }
480 $object = new Contact($this->db);
481 } elseif ($type === Categorie::TYPE_MEMBER) {
482 if (!DolibarrApiAccess::$user->hasRight('adherent', 'creer')) {
483 throw new RestException(401);
484 }
485 $object = new Adherent($this->db);
486 } else {
487 throw new RestException(401, "this type is not recognized yet.");
488 }
489
490 if (!empty($object)) {
491 $result = $object->fetch('', $object_ref);
492 if ($result > 0) {
493 $result = $this->category->add_type($object, $type);
494 if ($result < 0) {
495 if ($this->category->error != 'DB_ERROR_RECORD_ALREADY_EXISTS') {
496 throw new RestException(500, 'Error when linking object', array_merge(array($this->category->error), $this->category->errors));
497 }
498 }
499 } else {
500 throw new RestException(500, 'Error when fetching object', array_merge(array($object->error), $object->errors));
501 }
502
503 return array(
504 'success' => array(
505 'code' => 200,
506 'message' => 'Objects succefully linked to the category'
507 )
508 );
509 }
510
511 throw new RestException(401);
512 }
513
526 public function unlinkObjectById($id, $type, $object_id)
527 {
528 if (empty($type) || empty($object_id)) {
529 throw new RestException(401);
530 }
531
532 if (!DolibarrApiAccess::$user->rights->categorie->lire) {
533 throw new RestException(401);
534 }
535
536 $result = $this->category->fetch($id);
537 if (!$result) {
538 throw new RestException(404, 'category not found');
539 }
540
541 if ($type === Categorie::TYPE_PRODUCT) {
542 if (!(DolibarrApiAccess::$user->rights->produit->creer || DolibarrApiAccess::$user->rights->service->creer)) {
543 throw new RestException(401);
544 }
545 $object = new Product($this->db);
546 } elseif ($type === Categorie::TYPE_CUSTOMER) {
547 if (!DolibarrApiAccess::$user->rights->societe->creer) {
548 throw new RestException(401);
549 }
550 $object = new Societe($this->db);
551 } elseif ($type === Categorie::TYPE_SUPPLIER) {
552 if (!DolibarrApiAccess::$user->rights->societe->creer) {
553 throw new RestException(401);
554 }
555 $object = new Societe($this->db);
556 } elseif ($type === Categorie::TYPE_CONTACT) {
557 if (!DolibarrApiAccess::$user->rights->societe->contact->creer) {
558 throw new RestException(401);
559 }
560 $object = new Contact($this->db);
561 } elseif ($type === Categorie::TYPE_MEMBER) {
562 if (!DolibarrApiAccess::$user->hasRight('adherent', 'creer')) {
563 throw new RestException(401);
564 }
565 $object = new Adherent($this->db);
566 } else {
567 throw new RestException(401, "this type is not recognized yet.");
568 }
569
570 if (!empty($object)) {
571 $result = $object->fetch((int) $object_id);
572 if ($result > 0) {
573 $result = $this->category->del_type($object, $type);
574 if ($result < 0) {
575 throw new RestException(500, 'Error when unlinking object', array_merge(array($this->category->error), $this->category->errors));
576 }
577 } else {
578 throw new RestException(500, 'Error when fetching object', array_merge(array($object->error), $object->errors));
579 }
580
581 return array(
582 'success' => array(
583 'code' => 200,
584 'message' => 'Objects succefully unlinked from the category'
585 )
586 );
587 }
588
589 throw new RestException(401);
590 }
591
604 public function unlinkObjectByRef($id, $type, $object_ref)
605 {
606 if (empty($type) || empty($object_ref)) {
607 throw new RestException(401);
608 }
609
610 if (!DolibarrApiAccess::$user->rights->categorie->lire) {
611 throw new RestException(401);
612 }
613
614 $result = $this->category->fetch($id);
615 if (!$result) {
616 throw new RestException(404, 'category not found');
617 }
618
619 if ($type === Categorie::TYPE_PRODUCT) {
620 if (!(DolibarrApiAccess::$user->rights->produit->creer || DolibarrApiAccess::$user->rights->service->creer)) {
621 throw new RestException(401);
622 }
623 $object = new Product($this->db);
624 } elseif ($type === Categorie::TYPE_CUSTOMER) {
625 if (!DolibarrApiAccess::$user->rights->societe->creer) {
626 throw new RestException(401);
627 }
628 $object = new Societe($this->db);
629 } elseif ($type === Categorie::TYPE_SUPPLIER) {
630 if (!DolibarrApiAccess::$user->rights->societe->creer) {
631 throw new RestException(401);
632 }
633 $object = new Societe($this->db);
634 } elseif ($type === Categorie::TYPE_CONTACT) {
635 if (!DolibarrApiAccess::$user->rights->societe->contact->creer) {
636 throw new RestException(401);
637 }
638 $object = new Contact($this->db);
639 } elseif ($type === Categorie::TYPE_MEMBER) {
640 if (!DolibarrApiAccess::$user->hasRight('adherent', 'creer')) {
641 throw new RestException(401);
642 }
643 $object = new Adherent($this->db);
644 } else {
645 throw new RestException(401, "this type is not recognized yet.");
646 }
647
648 if (!empty($object)) {
649 $result = $object->fetch('', (string) $object_ref);
650 if ($result > 0) {
651 $result = $this->category->del_type($object, $type);
652 if ($result < 0) {
653 throw new RestException(500, 'Error when unlinking object', array_merge(array($this->category->error), $this->category->errors));
654 }
655 } else {
656 throw new RestException(500, 'Error when fetching object', array_merge(array($object->error), $object->errors));
657 }
658
659 return array(
660 'success' => array(
661 'code' => 200,
662 'message' => 'Objects succefully unlinked from the category'
663 )
664 );
665 }
666
667 throw new RestException(401);
668 }
669
670
671 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
678 protected function _cleanObjectDatas($object)
679 {
680 // phpcs:enable
681 $object = parent::_cleanObjectDatas($object);
682
683 // Remove fields not relevent to categories
684 unset($object->MAP_CAT_FK);
685 unset($object->MAP_CAT_TABLE);
686 unset($object->MAP_OBJ_CLASS);
687 unset($object->MAP_OBJ_TABLE);
688 unset($object->country);
689 unset($object->country_id);
690 unset($object->country_code);
691 unset($object->total_ht);
692 unset($object->total_ht);
693 unset($object->total_localtax1);
694 unset($object->total_localtax2);
695 unset($object->total_ttc);
696 unset($object->total_tva);
697 unset($object->lines);
698 unset($object->civility_id);
699 unset($object->name);
700 unset($object->lastname);
701 unset($object->firstname);
702 unset($object->shipping_method_id);
703 unset($object->fk_delivery_address);
704 unset($object->cond_reglement);
705 unset($object->cond_reglement_id);
706 unset($object->mode_reglement_id);
707 unset($object->barcode_type_coder);
708 unset($object->barcode_type_label);
709 unset($object->barcode_type_code);
710 unset($object->barcode_type);
711 unset($object->canvas);
712 unset($object->cats);
713 unset($object->motherof);
714 unset($object->context);
715 unset($object->socid);
716 unset($object->thirdparty);
717 unset($object->contact);
718 unset($object->contact_id);
719 unset($object->user);
720 unset($object->fk_account);
721 unset($object->fk_project);
722 unset($object->note);
723 unset($object->statut);
724
725 return $object;
726 }
727
736 private function _validate($data)
737 {
738 $category = array();
739 foreach (Categories::$FIELDS as $field) {
740 if (!isset($data[$field])) {
741 throw new RestException(400, "$field field missing");
742 }
743 $category[$field] = $data[$field];
744 }
745 return $category;
746 }
747
759 public function getObjects($id, $type, $onlyids = 0)
760 {
761 dol_syslog("getObjects($id, $type, $onlyids)", LOG_DEBUG);
762
763 if (!DolibarrApiAccess::$user->rights->categorie->lire) {
764 throw new RestException(401);
765 }
766
767 if (empty($type)) {
768 throw new RestException(500, 'The "type" parameter is required.');
769 }
770
771 $result = $this->category->fetch($id);
772 if (!$result) {
773 throw new RestException(404, 'category not found');
774 }
775
776 if (!DolibarrApi::_checkAccessToResource('categorie', $this->category->id)) {
777 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
778 }
779
780 $result = $this->category->getObjectsInCateg($type, $onlyids);
781
782 if ($result < 0) {
783 throw new RestException(503, 'Error when retrieving objects list : '.$this->category->error);
784 }
785
786 $objects = $result;
787 $cleaned_objects = array();
788 $objects_api = null;
789 if ($type == 'member') {
790 $objects_api = new Members();
791 } elseif ($type == 'customer' || $type == 'supplier') {
792 $objects_api = new Thirdparties();
793 } elseif ($type == 'product') {
794 $objects_api = new Products();
795 } elseif ($type == 'contact') {
796 $objects_api = new Contacts();
797 } elseif ($type == 'project') {
798 $objects_api = new Projects();
799 }
800 if (is_object($objects_api)) {
801 foreach ($objects as $obj) {
802 $cleaned_objects[] = $objects_api->_cleanObjectDatas($obj);
803 }
804 }
805
806 return $cleaned_objects;
807 }
808}
Class to manage members of a foundation.
Class to manage categories.
__construct()
Constructor.
put($id, $request_data=null)
Update category.
unlinkObjectById($id, $type, $object_id)
Unlink an object from a category by id.
unlinkObjectByRef($id, $type, $object_ref)
Unlink an object from a category by ref.
_validate($data)
Validate fields before create or update object.
post($request_data=null)
Create category object.
_cleanObjectDatas($object)
Clean sensible object datas.
getObjects($id, $type, $onlyids=0)
Get the list of objects in a category.
getListForObject($id, $type, $sortfield="s.rowid", $sortorder='ASC', $limit=0, $page=0)
List categories of an object.
linkObjectById($id, $type, $object_id)
Link an object to a category by id.
linkObjectByRef($id, $type, $object_ref)
Link an object to a category by ref.
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $type='', $sqlfilters='', $properties='')
List categories.
Class for API REST v1.
Definition api.class.php:31
_filterObjectProperties($object, $properties)
Filter properties that will be returned on object.
static _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid')
Check access by user to a given resource.
_checkValForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
Definition api.class.php:85
Class to manage products or services.
Class to manage third parties objects (customers, suppliers, prospects...)
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Contact()
Old copy.
Definition index.php:572