dolibarr 18.0.6
categorie.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2005 Matthieu Valleton <mv@seeschloss.org>
3 * Copyright (C) 2005 Davoleau Brice <brice.davoleau@gmail.com>
4 * Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
5 * Copyright (C) 2006-2012 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2006-2012 Laurent Destailleur <eldy@users.sourceforge.net>
7 * Copyright (C) 2007 Patrick Raguin <patrick.raguin@gmail.com>
8 * Copyright (C) 2013-2016 Juanjo Menent <jmenent@2byte.es>
9 * Copyright (C) 2013-2018 Philippe Grand <philippe.grand@atoo-net.com>
10 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
11 * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
12 * Copyright (C) 2016 Charlie Benke <charlie@patas-monkey.com>
13 * Copyright (C) 2018-2023 Frédéric France <frederic.france@netlogic.fr>
14 * Copyright (C) 2023 Benjamin Falière <benjamin.faliere@altairis.fr>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program. If not, see <https://www.gnu.org/licenses/>.
28 */
29
36require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
37require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
38require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php';
39require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
40require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
41require_once DOL_DOCUMENT_ROOT.'/knowledgemanagement/class/knowledgerecord.class.php';
42
43
48{
49 // Categories types (we use string because we want to accept any modules/types in a future)
50 const TYPE_PRODUCT = 'product';
51 const TYPE_SUPPLIER = 'supplier';
52 const TYPE_CUSTOMER = 'customer';
53 const TYPE_MEMBER = 'member';
54 const TYPE_CONTACT = 'contact';
55 const TYPE_USER = 'user';
56 const TYPE_PROJECT = 'project';
57 const TYPE_ACCOUNT = 'bank_account';
58 const TYPE_BANK_LINE = 'bank_line';
59 const TYPE_WAREHOUSE = 'warehouse';
60 const TYPE_ACTIONCOMM = 'actioncomm';
61 const TYPE_WEBSITE_PAGE = 'website_page';
62 const TYPE_TICKET = 'ticket';
63 const TYPE_KNOWLEDGEMANAGEMENT = 'knowledgemanagement';
64
68 public $picto = 'category';
69
70
74 protected $MAP_ID = array(
75 'product' => 0,
76 'supplier' => 1,
77 'customer' => 2,
78 'member' => 3,
79 'contact' => 4,
80 'bank_account' => 5,
81 'project' => 6,
82 'user' => 7,
83 'bank_line' => 8,
84 'warehouse' => 9,
85 'actioncomm' => 10,
86 'website_page' => 11,
87 'ticket' => 12,
88 'knowledgemanagement' => 13
89 );
90
96 public static $MAP_ID_TO_CODE = array(
97 0 => 'product',
98 1 => 'supplier',
99 2 => 'customer',
100 3 => 'member',
101 4 => 'contact',
102 5 => 'bank_account',
103 6 => 'project',
104 7 => 'user',
105 8 => 'bank_line',
106 9 => 'warehouse',
107 10 => 'actioncomm',
108 11 => 'website_page',
109 12 => 'ticket',
110 13 => 'knowledgemanagement'
111 );
112
118 public $MAP_CAT_FK = array(
119 'customer' => 'soc',
120 'supplier' => 'soc',
121 'contact' => 'socpeople',
122 'bank_account' => 'account',
123 );
124
130 public $MAP_CAT_TABLE = array(
131 'customer' => 'societe',
132 'supplier' => 'fournisseur',
133 'bank_account'=> 'account',
134 );
135
141 public $MAP_OBJ_CLASS = array(
142 'product' => 'Product',
143 'customer' => 'Societe',
144 'supplier' => 'Fournisseur',
145 'member' => 'Adherent',
146 'contact' => 'Contact',
147 'user' => 'User',
148 'account' => 'Account', // old for bank account
149 'bank_account' => 'Account',
150 'project' => 'Project',
151 'warehouse'=> 'Entrepot',
152 'actioncomm' => 'ActionComm',
153 'website_page' => 'WebsitePage',
154 'ticket' => 'Ticket',
155 'knowledgemanagement' => 'KnowledgeRecord'
156 );
157
163 public static $MAP_TYPE_TITLE_AREA = array(
164 'product' => 'ProductsCategoriesArea',
165 'customer' => 'CustomersCategoriesArea',
166 'supplier' => 'SuppliersCategoriesArea',
167 'member' => 'MembersCategoriesArea',
168 'contact' => 'ContactsCategoriesArea',
169 'user' => 'UsersCategoriesArea',
170 'account' => 'AccountsCategoriesArea', // old for bank account
171 'bank_account' => 'AccountsCategoriesArea',
172 'project' => 'ProjectsCategoriesArea',
173 'warehouse'=> 'StocksCategoriesArea',
174 'actioncomm' => 'ActioncommCategoriesArea',
175 'website_page' => 'WebsitePageCategoriesArea'
176 );
177
182 public $MAP_OBJ_TABLE = array(
183 'customer' => 'societe',
184 'supplier' => 'societe',
185 'member' => 'adherent',
186 'contact' => 'socpeople',
187 'account' => 'bank_account', // old for bank account
188 'project' => 'projet',
189 'warehouse'=> 'entrepot',
190 'knowledgemanagement' => 'knowledgemanagement_knowledgerecord'
191 );
192
196 public $element = 'category';
197
201 public $table_element = 'categorie';
202
206 public $fk_parent;
207
211 public $label;
212
216 public $description;
217
221 public $color;
222
226 public $visible;
227
231 public $socid;
232
250 public $type;
251
255 public $cats = array();
256
260 public $motherof = array();
261
265 public $childs = array();
266
267
273 public function __construct($db)
274 {
275 global $hookmanager;
276
277 $this->db = $db;
278
279 if (is_object($hookmanager)) {
280 $hookmanager->initHooks(array('category'));
281 $parameters = array();
282 $reshook = $hookmanager->executeHooks('constructCategory', $parameters, $this); // Note that $action and $object may have been modified by some hooks
283 if ($reshook >= 0 && !empty($hookmanager->resArray)) {
284 foreach ($hookmanager->resArray as $mapList) {
285 $mapId = $mapList['id'];
286 $mapCode = $mapList['code'];
287 self::$MAP_ID_TO_CODE[$mapId] = $mapCode;
288 $this->MAP_ID[$mapCode] = $mapId;
289 $this->MAP_CAT_FK[$mapCode] = isset($mapList['cat_fk']) ? $mapList['cat_fk'] : null;
290 $this->MAP_CAT_TABLE[$mapCode] = isset($mapList['cat_table']) ? $mapList['cat_table'] : null;
291 $this->MAP_OBJ_CLASS[$mapCode] = $mapList['obj_class'];
292 $this->MAP_OBJ_TABLE[$mapCode] = $mapList['obj_table'];
293 }
294 }
295 }
296 }
297
303 public function getMapList()
304 {
305 $mapList = array();
306
307 foreach ($this->MAP_ID as $mapCode => $mapId) {
308 $mapList[] = array(
309 'id' => $mapId,
310 'code' => $mapCode,
311 'cat_fk' => (empty($this->MAP_CAT_FK[$mapCode]) ? $mapCode : $this->MAP_CAT_FK[$mapCode]),
312 'cat_table' => (empty($this->MAP_CAT_TABLE[$mapCode]) ? $mapCode : $this->MAP_CAT_TABLE[$mapCode]),
313 'obj_class' => (empty($this->MAP_OBJ_CLASS[$mapCode]) ? $mapCode : $this->MAP_OBJ_CLASS[$mapCode]),
314 'obj_table' => (empty($this->MAP_OBJ_TABLE[$mapCode]) ? $mapCode : $this->MAP_OBJ_TABLE[$mapCode])
315 );
316 }
317
318 return $mapList;
319 }
320
330 public function fetch($id, $label = '', $type = null, $ref_ext = '')
331 {
332 global $conf;
333
334 // Check parameters
335 if (empty($id) && empty($label) && empty($ref_ext)) {
336 $this->error = "No category to search for";
337 return -1;
338 }
339 if (!is_null($type) && !is_numeric($type)) {
340 $type = $this->MAP_ID[$type];
341 }
342
343 $sql = "SELECT rowid, fk_parent, entity, label, description, color, fk_soc, visible, type, ref_ext";
344 $sql .= ", date_creation, tms, fk_user_creat, fk_user_modif";
345 $sql .= " FROM ".MAIN_DB_PREFIX."categorie";
346 if ($id) {
347 $sql .= " WHERE rowid = ".((int) $id);
348 } elseif (!empty($ref_ext)) {
349 $sql .= " WHERE ref_ext LIKE '".$this->db->escape($ref_ext)."'";
350 } else {
351 $sql .= " WHERE label = '".$this->db->escape($label)."' AND entity IN (".getEntity('category').")";
352 if (!is_null($type)) {
353 $sql .= " AND type = ".((int) $type);
354 }
355 }
356
357 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
358 $resql = $this->db->query($sql);
359 if ($resql) {
360 if ($this->db->num_rows($resql) > 0) {
361 $res = $this->db->fetch_array($resql);
362
363 $this->id = $res['rowid'];
364 //$this->ref = $res['rowid'];
365 $this->fk_parent = (int) $res['fk_parent'];
366 $this->label = $res['label'];
367 $this->description = $res['description'];
368 $this->color = $res['color'];
369 $this->socid = (int) $res['fk_soc'];
370 $this->visible = (int) $res['visible'];
371 $this->type = (int) $res['type'];
372 $this->ref_ext = $res['ref_ext'];
373 $this->entity = (int) $res['entity'];
374 $this->date_creation = $this->db->jdate($res['date_creation']);
375 $this->date_modification = $this->db->jdate($res['tms']);
376 $this->user_creation_id = (int) $res['fk_user_creat'];
377 $this->user_modification_id = (int) $res['fk_user_modif'];
378 $this->user_creation = (int) $res['fk_user_creat'];
379 $this->user_modification = (int) $res['fk_user_modif'];
380
381 // Retrieve all extrafield
382 // fetch optionals attributes and labels
383 $this->fetch_optionals();
384
385 $this->db->free($resql);
386
387 // multilangs
388 if (getDolGlobalInt('MAIN_MULTILANGS')) {
389 $this->getMultiLangs();
390 }
391
392 return 1;
393 } else {
394 $this->error = "No category found";
395 return 0;
396 }
397 } else {
398 dol_print_error($this->db);
399 $this->error = $this->db->lasterror;
400 $this->errors[] = $this->db->lasterror;
401 return -1;
402 }
403 }
404
414 public function create($user)
415 {
416 global $conf, $langs, $hookmanager;
417 $langs->load('categories');
418
419 $type = $this->type;
420
421 if (!is_numeric($type)) {
422 $type = $this->MAP_ID[$type];
423 }
424
425 $error = 0;
426
427 dol_syslog(get_class($this).'::create', LOG_DEBUG);
428
429 // Clean parameters
430 $this->label = trim($this->label);
431 $this->description = trim($this->description);
432 $this->color = trim($this->color);
433 $this->import_key = trim($this->import_key);
434 $this->ref_ext = trim($this->ref_ext);
435 if (empty($this->visible)) {
436 $this->visible = 0;
437 }
438 $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
439
440 if ($this->already_exists()) {
441 $this->error = $langs->trans("ImpossibleAddCat", $this->label);
442 $this->error .= " : ".$langs->trans("CategoryExistsAtSameLevel");
443 dol_syslog($this->error, LOG_WARNING);
444 return -4;
445 }
446
447 $this->db->begin();
448 $now = dol_now();
449 $sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie (";
450 $sql .= "fk_parent,";
451 $sql .= " label,";
452 $sql .= " description,";
453 $sql .= " color,";
454 if (!empty($conf->global->CATEGORY_ASSIGNED_TO_A_CUSTOMER)) {
455 $sql .= "fk_soc,";
456 }
457 $sql .= " visible,";
458 $sql .= " type,";
459 $sql .= " import_key,";
460 $sql .= " ref_ext,";
461 $sql .= " entity,";
462 $sql .= " date_creation,";
463 $sql .= " fk_user_creat";
464 $sql .= ") VALUES (";
465 $sql .= (int) $this->fk_parent.",";
466 $sql .= "'".$this->db->escape($this->label)."', ";
467 $sql .= "'".$this->db->escape($this->description)."', ";
468 $sql .= "'".$this->db->escape($this->color)."', ";
469 if (!empty($conf->global->CATEGORY_ASSIGNED_TO_A_CUSTOMER)) {
470 $sql .= ($this->socid > 0 ? $this->socid : 'null').", ";
471 }
472 $sql .= "'".$this->db->escape($this->visible)."', ";
473 $sql .= ((int) $type).", ";
474 $sql .= (!empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : 'null').", ";
475 $sql .= (!empty($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : 'null').", ";
476 $sql .= (int) $conf->entity.", ";
477 $sql .= "'".$this->db->idate($now)."', ";
478 $sql .= (int) $user->id;
479 $sql .= ")";
480
481 $res = $this->db->query($sql);
482 if ($res) {
483 $id = $this->db->last_insert_id(MAIN_DB_PREFIX."categorie");
484
485 if ($id > 0) {
486 $this->id = $id;
487
488 $action = 'create';
489
490 // Actions on extra fields
491 if (!$error) {
492 $result = $this->insertExtraFields();
493 if ($result < 0) {
494 $error++;
495 }
496 }
497
498 if (!$error) {
499 // Call trigger
500 $result = $this->call_trigger('CATEGORY_CREATE', $user);
501 if ($result < 0) {
502 $error++;
503 }
504 // End call triggers
505 }
506
507 if (!$error) {
508 $this->db->commit();
509 return $id;
510 } else {
511 $this->db->rollback();
512 return -3;
513 }
514 } else {
515 $this->db->rollback();
516 return -2;
517 }
518 } else {
519 $this->error = $this->db->error();
520 $this->db->rollback();
521 return -1;
522 }
523 }
524
533 public function update(User $user)
534 {
535 global $conf, $langs, $hookmanager;
536
537 $error = 0;
538
539 // Clean parameters
540 $this->label = trim($this->label);
541 $this->description = trim($this->description);
542 $this->ref_ext = trim($this->ref_ext);
543 $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
544 $this->visible = ($this->visible != "" ? intval($this->visible) : 0);
545
546 if ($this->already_exists()) {
547 $this->error = $langs->trans("ImpossibleUpdateCat");
548 $this->error .= " : ".$langs->trans("CategoryExistsAtSameLevel");
549 return -1;
550 }
551
552 $this->db->begin();
553
554 $sql = "UPDATE ".MAIN_DB_PREFIX."categorie";
555 $sql .= " SET label = '".$this->db->escape($this->label)."',";
556 $sql .= " description = '".$this->db->escape($this->description)."',";
557 $sql .= " ref_ext = '".$this->db->escape($this->ref_ext)."',";
558 $sql .= " color = '".$this->db->escape($this->color)."'";
559 if (!empty($conf->global->CATEGORY_ASSIGNED_TO_A_CUSTOMER)) {
560 $sql .= ", fk_soc = ".($this->socid > 0 ? $this->socid : 'null');
561 }
562 $sql .= ", visible = ".(int) $this->visible;
563 $sql .= ", fk_parent = ".(int) $this->fk_parent;
564 $sql .= ", fk_user_modif = ".(int) $user->id;
565 $sql .= " WHERE rowid = ".((int) $this->id);
566
567 dol_syslog(get_class($this)."::update", LOG_DEBUG);
568 if ($this->db->query($sql)) {
569 $action = 'update';
570
571 // Actions on extra fields
572 if (!$error) {
573 $result = $this->insertExtraFields();
574 if ($result < 0) {
575 $error++;
576 }
577 }
578
579 if (!$error) {
580 // Call trigger
581 $result = $this->call_trigger('CATEGORY_MODIFY', $user);
582 if ($result < 0) {
583 $error++; $this->db->rollback(); return -1;
584 }
585 // End call triggers
586 }
587
588 $this->db->commit();
589
590 return 1;
591 } else {
592 $this->db->rollback();
593 dol_print_error($this->db);
594 return -1;
595 }
596 }
597
605 public function delete($user, $notrigger = 0)
606 {
607 global $conf, $langs;
608
609 $error = 0;
610
611 // Clean parameters
612 $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
613
614 dol_syslog(get_class($this)."::remove");
615
616 $this->db->begin();
617
618 if (!$error && !$notrigger) {
619 // Call trigger
620 $result = $this->call_trigger('CATEGORY_DELETE', $user);
621 if ($result < 0) {
622 $error++;
623 }
624 // End call triggers
625 }
626
627 /* FIX #1317 : Check for child category and move up 1 level*/
628 if (!$error) {
629 $sql = "UPDATE ".MAIN_DB_PREFIX."categorie";
630 $sql .= " SET fk_parent = ".((int) $this->fk_parent);
631 $sql .= " WHERE fk_parent = ".((int) $this->id);
632
633 if (!$this->db->query($sql)) {
634 $this->error = $this->db->lasterror();
635 $error++;
636 }
637 }
638
639 $arraydelete = array(
640 'categorie_account' => 'fk_categorie',
641 'categorie_actioncomm' => 'fk_categorie',
642 'categorie_contact' => 'fk_categorie',
643 'categorie_fournisseur' => 'fk_categorie',
644 'categorie_knowledgemanagement' => array('field' => 'fk_categorie', 'enabled' => isModEnabled('knowledgemanagement')),
645 'categorie_member' => 'fk_categorie',
646 'categorie_user' => 'fk_categorie',
647 'categorie_product' => 'fk_categorie',
648 'categorie_project' => 'fk_categorie',
649 'categorie_societe' => 'fk_categorie',
650 'categorie_ticket' => array('field' => 'fk_categorie', 'enabled' => isModEnabled('ticket')),
651 'categorie_warehouse' => 'fk_categorie',
652 'categorie_website_page' => array('field' => 'fk_categorie', 'enabled' => isModEnabled('website')),
653 'bank_class' => 'fk_categ',
654 'categorie_lang' => 'fk_category',
655 'categorie' => 'rowid',
656 );
657 foreach ($arraydelete as $key => $value) {
658 if (is_array($value)) {
659 if (empty($value['enabled'])) {
660 continue;
661 }
662 $value = $value['field'];
663 }
664 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$key;
665 $sql .= " WHERE ".$value." = ".((int) $this->id);
666 if (!$this->db->query($sql)) {
667 $this->errors[] = $this->db->lasterror();
668 dol_syslog("Error sql=".$sql." ".$this->error, LOG_ERR);
669 $error++;
670 }
671 }
672
673 // Removed extrafields
674 if (!$error) {
675 $result = $this->deleteExtraFields();
676 if ($result < 0) {
677 $error++;
678 dol_syslog(get_class($this)."::delete erreur ".$this->error, LOG_ERR);
679 }
680 }
681
682 if (!$error) {
683 $this->db->commit();
684 return 1;
685 } else {
686 $this->db->rollback();
687 return -1;
688 }
689 }
690
691 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
700 public function add_type($obj, $type = '')
701 {
702 // phpcs:enable
703 global $user, $conf;
704
705 $error = 0;
706
707 if ($this->id == -1) {
708 return -2;
709 }
710
711 if (empty($type)) {
712 $type = $obj->element;
713 }
714
715 dol_syslog(get_class($this).'::add_type', LOG_DEBUG);
716
717 $this->db->begin();
718
719 $sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type]);
720 $sql .= " (fk_categorie, fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type]).")";
721 $sql .= " VALUES (".((int) $this->id).", ".((int) $obj->id).")";
722
723 if ($this->db->query($sql)) {
724 if (!empty($conf->global->CATEGORIE_RECURSIV_ADD)) {
725 $sql = 'SELECT fk_parent FROM '.MAIN_DB_PREFIX.'categorie';
726 $sql .= " WHERE rowid = ".((int) $this->id);
727
728 dol_syslog(get_class($this)."::add_type", LOG_DEBUG);
729 $resql = $this->db->query($sql);
730 if ($resql) {
731 if ($this->db->num_rows($resql) > 0) {
732 $objparent = $this->db->fetch_object($resql);
733
734 if (!empty($objparent->fk_parent)) {
735 $cat = new Categorie($this->db);
736 $cat->id = $objparent->fk_parent;
737 if (!$cat->containsObject($type, $obj->id)) {
738 $result = $cat->add_type($obj, $type);
739 if ($result < 0) {
740 $this->error = $cat->error;
741 $error++;
742 }
743 }
744 }
745 }
746 } else {
747 $error++;
748 $this->error = $this->db->lasterror();
749 }
750
751 if ($error) {
752 $this->db->rollback();
753 return -1;
754 }
755 }
756
757 // Call trigger
758 $this->context = array('linkto'=>$obj); // Save object we want to link category to into category instance to provide information to trigger
759 $result = $this->call_trigger('CATEGORY_LINK', $user);
760 if ($result < 0) {
761 $error++;
762 }
763 // End call triggers
764
765 if (!$error) {
766 $this->db->commit();
767 return 1;
768 } else {
769 $this->db->rollback();
770 return -2;
771 }
772 } else {
773 $this->db->rollback();
774 if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
775 $this->error = $this->db->lasterrno();
776 return -3;
777 } else {
778 $this->error = $this->db->lasterror();
779 }
780 return -1;
781 }
782 }
783
784 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
793 public function del_type($obj, $type)
794 {
795 // phpcs:enable
796 global $user, $langs, $conf;
797
798 $error = 0;
799
800 // For backward compatibility
801 if ($type == 'societe') {
802 $type = 'customer';
803 dol_syslog(get_class($this)."::del_type(): type 'societe' is deprecated, please use 'customer' instead", LOG_WARNING);
804 } elseif ($type == 'fournisseur') {
805 $type = 'supplier';
806 dol_syslog(get_class($this)."::del_type(): type 'fournisseur' is deprecated, please use 'supplier' instead", LOG_WARNING);
807 }
808
809 $this->db->begin();
810
811 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type]);
812 $sql .= " WHERE fk_categorie = ".((int) $this->id);
813 $sql .= " AND fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = ".((int) $obj->id);
814
815 dol_syslog(get_class($this).'::del_type', LOG_DEBUG);
816 if ($this->db->query($sql)) {
817 // Call trigger
818 $this->context = array('unlinkoff'=>$obj); // Save object we want to link category to into category instance to provide information to trigger
819 $result = $this->call_trigger('CATEGORY_UNLINK', $user);
820 if ($result < 0) {
821 $error++;
822 }
823 // End call triggers
824
825 if (!$error) {
826 $this->db->commit();
827 return 1;
828 } else {
829 $this->db->rollback();
830 return -2;
831 }
832 } else {
833 $this->db->rollback();
834 $this->error = $this->db->lasterror();
835 return -1;
836 }
837 }
838
853 public function getObjectsInCateg($type, $onlyids = 0, $limit = 0, $offset = 0, $sortfield = '', $sortorder = 'ASC', $filter = array(), $filtermode = 'AND')
854 {
855 global $user;
856
857 $objs = array();
858
859 $classnameforobj = $this->MAP_OBJ_CLASS[$type];
860 $obj = new $classnameforobj($this->db);
861
862 $sql = "SELECT c.fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type]);
863 $sql .= " FROM ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type])." as c";
864 $sql .= ", ".MAIN_DB_PREFIX.(empty($this->MAP_OBJ_TABLE[$type]) ? $type : $this->MAP_OBJ_TABLE[$type])." as o";
865 $sql .= " WHERE o.entity IN (".getEntity($obj->element).")";
866 $sql .= " AND c.fk_categorie = ".((int) $this->id);
867 // Compatibility with actioncomm table which has id instead of rowid
868 if ((array_key_exists($type, $this->MAP_OBJ_TABLE) && $this->MAP_OBJ_TABLE[$type] == "actioncomm") || $type == "actioncomm") {
869 $sql .= " AND c.fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = o.id";
870 } else {
871 $sql .= " AND c.fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = o.rowid";
872 }
873 // Protection for external users
874 if (($type == 'customer' || $type == 'supplier') && $user->socid > 0) {
875 $sql .= " AND o.rowid = ".((int) $user->socid);
876 }
877 // Manage filter
878 $sqlwhere = array();
879 if (count($filter) > 0) {
880 foreach ($filter as $key => $value) {
881 if ($key == 'o.rowid') {
882 $sqlwhere[] = $key." = ".((int) $value);
883 } elseif ($key == 'customsql') {
884 $sqlwhere[] = $value;
885 }
886 }
887 }
888 if (count($sqlwhere) > 0) {
889 $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
890 }
891 $sql .= $this->db->order($sortfield, $sortorder);
892 if ($limit > 0 || $offset > 0) {
893 $sql .= $this->db->plimit($limit + 1, $offset);
894 }
895
896 dol_syslog(get_class($this)."::getObjectsInCateg", LOG_DEBUG);
897
898 $resql = $this->db->query($sql);
899 if ($resql) {
900 while ($rec = $this->db->fetch_array($resql)) {
901 if ($onlyids) {
902 $objs[] = $rec['fk_'.(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])];
903 } else {
904 $classnameforobj = $this->MAP_OBJ_CLASS[$type];
905
906 $obj = new $classnameforobj($this->db);
907 $obj->fetch($rec['fk_'.(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])]);
908
909 $objs[] = $obj;
910 }
911 }
912 return $objs;
913 } else {
914 $this->error = $this->db->error().' sql='.$sql;
915 return -1;
916 }
917 }
918
927 public function containsObject($type, $object_id)
928 {
929 $sql = "SELECT COUNT(*) as nb FROM ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type]);
930 $sql .= " WHERE fk_categorie = ".((int) $this->id)." AND fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = ".((int) $object_id);
931 dol_syslog(get_class($this)."::containsObject", LOG_DEBUG);
932 $resql = $this->db->query($sql);
933 if ($resql) {
934 return $this->db->fetch_object($resql)->nb;
935 } else {
936 $this->error = $this->db->error().' sql='.$sql;
937 return -1;
938 }
939 }
940
952 public function getListForItem($id, $type = 'customer', $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
953 {
954 global $conf;
955
956 $categories = array();
957
958 $type = sanitizeVal($type, 'aZ09');
959
960 $sub_type = $type;
961 $subcol_name = "fk_".$type;
962 if ($type == "customer") {
963 $sub_type = "societe";
964 $subcol_name = "fk_soc";
965 }
966 if ($type == "supplier") {
967 $sub_type = "fournisseur";
968 $subcol_name = "fk_soc";
969 }
970 if ($type == "contact") {
971 $subcol_name = "fk_socpeople";
972 }
973
974 $idoftype = array_search($type, self::$MAP_ID_TO_CODE);
975
976 $sql = "SELECT s.rowid";
977 $sql .= " FROM ".MAIN_DB_PREFIX."categorie as s, ".MAIN_DB_PREFIX."categorie_".$sub_type." as sub";
978 $sql .= ' WHERE s.entity IN ('.getEntity('category').')';
979 $sql .= ' AND s.type='.((int) $idoftype);
980 $sql .= ' AND s.rowid = sub.fk_categorie';
981 $sql .= " AND sub.".$subcol_name." = ".((int) $id);
982
983 $sql .= $this->db->order($sortfield, $sortorder);
984
985 $offset = 0;
986 $nbtotalofrecords = '';
987 if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
988 $result = $this->db->query($sql);
989 $nbtotalofrecords = $this->db->num_rows($result);
990 if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
991 $page = 0;
992 $offset = 0;
993 }
994 }
995
996 if ($limit) {
997 if ($page < 0) {
998 $page = 0;
999 }
1000 $offset = $limit * $page;
1001
1002 $sql .= $this->db->plimit($limit + 1, $offset);
1003 }
1004
1005 $result = $this->db->query($sql);
1006 if ($result) {
1007 $i = 0;
1008 $num = $this->db->num_rows($result);
1009 $min = min($num, ($limit <= 0 ? $num : $limit));
1010 while ($i < $min) {
1011 $obj = $this->db->fetch_object($result);
1012 $category_static = new Categorie($this->db);
1013 if ($category_static->fetch($obj->rowid)) {
1014 $categories[$i]['id'] = $category_static->id;
1015 $categories[$i]['fk_parent'] = $category_static->fk_parent;
1016 $categories[$i]['label'] = $category_static->label;
1017 $categories[$i]['description'] = $category_static->description;
1018 $categories[$i]['color'] = $category_static->color;
1019 $categories[$i]['socid'] = $category_static->socid;
1020 $categories[$i]['ref_ext'] = $category_static->ref_ext;
1021 $categories[$i]['visible'] = $category_static->visible;
1022 $categories[$i]['type'] = $category_static->type;
1023 $categories[$i]['entity'] = $category_static->entity;
1024 $categories[$i]['array_options'] = $category_static->array_options;
1025
1026 // multilangs
1027 if (getDolGlobalInt('MAIN_MULTILANGS') && isset($category_static->multilangs)) {
1028 $categories[$i]['multilangs'] = $category_static->multilangs;
1029 }
1030 }
1031 $i++;
1032 }
1033 } else {
1034 $this->error = $this->db->lasterror();
1035 return -1;
1036 }
1037 if (!count($categories)) {
1038 return 0;
1039 }
1040
1041 return $categories;
1042 }
1043
1044 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1050 public function get_filles()
1051 {
1052 // phpcs:enable
1053 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
1054 $sql .= " WHERE fk_parent = ".((int) $this->id);
1055 $sql .= " AND entity IN (".getEntity('category').")";
1056
1057 $res = $this->db->query($sql);
1058 if ($res) {
1059 $cats = array();
1060 while ($rec = $this->db->fetch_array($res)) {
1061 $cat = new Categorie($this->db);
1062 $cat->fetch($rec['rowid']);
1063 $cats[] = $cat;
1064 }
1065 return $cats;
1066 } else {
1067 dol_print_error($this->db);
1068 return -1;
1069 }
1070 }
1071
1072 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1078 protected function load_motherof()
1079 {
1080 // phpcs:enable
1081 $this->motherof = array();
1082
1083 // Load array[child]=parent
1084 $sql = "SELECT fk_parent as id_parent, rowid as id_son";
1085 $sql .= " FROM ".MAIN_DB_PREFIX."categorie";
1086 $sql .= " WHERE fk_parent != 0";
1087 $sql .= " AND entity IN (".getEntity('category').")";
1088
1089 dol_syslog(get_class($this)."::load_motherof", LOG_DEBUG);
1090 $resql = $this->db->query($sql);
1091 if ($resql) {
1092 while ($obj = $this->db->fetch_object($resql)) {
1093 $this->motherof[$obj->id_son] = $obj->id_parent;
1094 }
1095 return 1;
1096 } else {
1097 dol_print_error($this->db);
1098 return -1;
1099 }
1100 }
1101
1102 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1122 public function get_full_arbo($type, $markafterid = 0, $include = 0)
1123 {
1124 // phpcs:enable
1125 global $conf, $langs;
1126
1127 if (!is_numeric($type)) {
1128 $type = $this->MAP_ID[$type];
1129 }
1130 if (is_null($type)) {
1131 $this->error = 'BadValueForParameterType';
1132 return -1;
1133 }
1134
1135 if (is_string($markafterid)) {
1136 $markafterid = explode(',', $markafterid);
1137 } elseif (is_numeric($markafterid)) {
1138 if ($markafterid > 0) {
1139 $markafterid = array($markafterid);
1140 } else {
1141 $markafterid = array();
1142 }
1143 } elseif (!is_array($markafterid)) {
1144 $markafterid = array();
1145 }
1146
1147 $this->cats = array();
1148
1149 // Init this->motherof that is array(id_son=>id_parent, ...)
1150 $this->load_motherof();
1151 $current_lang = $langs->getDefaultLang();
1152
1153 // Init $this->cats array
1154 $sql = "SELECT DISTINCT c.rowid, c.label, c.ref_ext, c.description, c.color, c.fk_parent, c.visible"; // Distinct reduce pb with old tables with duplicates
1155 if (getDolGlobalInt('MAIN_MULTILANGS')) {
1156 $sql .= ", t.label as label_trans, t.description as description_trans";
1157 }
1158 $sql .= " FROM ".MAIN_DB_PREFIX."categorie as c";
1159 if (getDolGlobalInt('MAIN_MULTILANGS')) {
1160 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_lang as t ON t.fk_category=c.rowid AND t.lang='".$this->db->escape($current_lang)."'";
1161 }
1162 $sql .= " WHERE c.entity IN (".getEntity('category').")";
1163 $sql .= " AND c.type = ".(int) $type;
1164
1165 dol_syslog(get_class($this)."::get_full_arbo get category list", LOG_DEBUG);
1166 $resql = $this->db->query($sql);
1167 if ($resql) {
1168 $i = 0;
1169 while ($obj = $this->db->fetch_object($resql)) {
1170 $this->cats[$obj->rowid]['rowid'] = $obj->rowid;
1171 $this->cats[$obj->rowid]['id'] = $obj->rowid;
1172 $this->cats[$obj->rowid]['fk_parent'] = $obj->fk_parent;
1173 $this->cats[$obj->rowid]['label'] = !empty($obj->label_trans) ? $obj->label_trans : $obj->label;
1174 $this->cats[$obj->rowid]['description'] = !empty($obj->description_trans) ? $obj->description_trans : $obj->description;
1175 $this->cats[$obj->rowid]['color'] = $obj->color;
1176 $this->cats[$obj->rowid]['visible'] = $obj->visible;
1177 $this->cats[$obj->rowid]['ref_ext'] = $obj->ref_ext;
1178 $this->cats[$obj->rowid]['picto'] = 'category';
1179 $i++;
1180 }
1181 } else {
1182 dol_print_error($this->db);
1183 return -1;
1184 }
1185
1186 // We add the fullpath property to each elements of first level (no parent exists)
1187 dol_syslog(get_class($this)."::get_full_arbo call to buildPathFromId", LOG_DEBUG);
1188 foreach ($this->cats as $key => $val) {
1189 //print 'key='.$key.'<br>'."\n";
1190 $this->buildPathFromId($key, 0); // Process a branch from the root category key (this category has no parent)
1191 }
1192
1193 // Include or exclude leaf including $markafterid from tree
1194 if (count($markafterid) > 0) {
1195 $keyfiltercatid = '('.implode('|', $markafterid).')';
1196
1197 //print "Look to discard category ".$markafterid."\n";
1198 $keyfilter1 = '^'.$keyfiltercatid.'$';
1199 $keyfilter2 = '_'.$keyfiltercatid.'$';
1200 $keyfilter3 = '^'.$keyfiltercatid.'_';
1201 $keyfilter4 = '_'.$keyfiltercatid.'_';
1202 foreach ($this->cats as $key => $val) {
1203 $test = (preg_match('/'.$keyfilter1.'/', $val['fullpath']) || preg_match('/'.$keyfilter2.'/', $val['fullpath'])
1204 || preg_match('/'.$keyfilter3.'/', $val['fullpath']) || preg_match('/'.$keyfilter4.'/', $val['fullpath']));
1205
1206 if (($test && !$include) || (!$test && $include)) {
1207 unset($this->cats[$key]);
1208 }
1209 }
1210 }
1211
1212 dol_syslog(get_class($this)."::get_full_arbo dol_sort_array", LOG_DEBUG);
1213 $this->cats = dol_sort_array($this->cats, 'fulllabel', 'asc', true, false);
1214
1215 return $this->cats;
1216 }
1217
1228 private function buildPathFromId($id_categ, $protection = 1000)
1229 {
1230 //dol_syslog(get_class($this)."::buildPathFromId id_categ=".$id_categ." protection=".$protection, LOG_DEBUG);
1231
1232 if (!empty($this->cats[$id_categ]['fullpath'])) {
1233 // Already defined
1234 dol_syslog(get_class($this)."::buildPathFromId fullpath and fulllabel already defined", LOG_WARNING);
1235 return -1;
1236 }
1237
1238 // First build full array $motherof
1239 //$this->load_motherof(); // Disabled because already done by caller of buildPathFromId
1240
1241 // $this->cats[$id_categ] is supposed to be already an array. We just want to complete it with property fullpath and fulllabel
1242
1243 // Define fullpath and fulllabel
1244 $this->cats[$id_categ]['fullpath'] = '_'.$id_categ;
1245 $this->cats[$id_categ]['fulllabel'] = $this->cats[$id_categ]['label'];
1246 $i = 0; $cursor_categ = $id_categ;
1247 //print 'Work for id_categ='.$id_categ.'<br>'."\n";
1248 while ((empty($protection) || $i < $protection) && !empty($this->motherof[$cursor_categ])) {
1249 //print '&nbsp; cursor_categ='.$cursor_categ.' i='.$i.' '.$this->motherof[$cursor_categ].'<br>'."\n";
1250 $this->cats[$id_categ]['fullpath'] = '_'.$this->motherof[$cursor_categ].$this->cats[$id_categ]['fullpath'];
1251 $this->cats[$id_categ]['fulllabel'] = (empty($this->cats[$this->motherof[$cursor_categ]]) ? 'NotFound' : $this->cats[$this->motherof[$cursor_categ]]['label']).' >> '.$this->cats[$id_categ]['fulllabel'];
1252 //print '&nbsp; Result for id_categ='.$id_categ.' : '.$this->cats[$id_categ]['fullpath'].' '.$this->cats[$id_categ]['fulllabel'].'<br>'."\n";
1253 $i++;
1254 $cursor_categ = $this->motherof[$cursor_categ];
1255 }
1256 //print 'Result for id_categ='.$id_categ.' : '.$this->cats[$id_categ]['fullpath'].'<br>'."\n";
1257
1258 // We count number of _ to have level
1259 $nbunderscore = substr_count($this->cats[$id_categ]['fullpath'], '_');
1260 $this->cats[$id_categ]['level'] = ($nbunderscore ? $nbunderscore : null);
1261
1262 return 1;
1263 }
1264
1265
1266 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1274 public function get_all_categories($type = null, $parent = false)
1275 {
1276 // phpcs:enable
1277 if (!is_numeric($type)) {
1278 $type = $this->MAP_ID[$type];
1279 }
1280
1281 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
1282 $sql .= " WHERE entity IN (".getEntity('category').")";
1283 if (!is_null($type)) {
1284 $sql .= " AND type = ".(int) $type;
1285 }
1286 if ($parent) {
1287 $sql .= " AND fk_parent = 0";
1288 }
1289
1290 $res = $this->db->query($sql);
1291 if ($res) {
1292 $cats = array();
1293 while ($rec = $this->db->fetch_array($res)) {
1294 $cat = new Categorie($this->db);
1295 $cat->fetch($rec['rowid']);
1296 $cats[$rec['rowid']] = $cat;
1297 }
1298 return $cats;
1299 } else {
1300 dol_print_error($this->db);
1301 return -1;
1302 }
1303 }
1304
1305 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1312 public function get_main_categories($type = null)
1313 {
1314 // phpcs:enable
1315 return $this->get_all_categories($type, true);
1316 }
1317
1318 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1324 public function already_exists()
1325 {
1326 // phpcs:enable
1327 $type = $this->type;
1328
1329 if (!is_numeric($type)) {
1330 $type = $this->MAP_ID[$type];
1331 }
1332
1333 /* We have to select any rowid from llx_categorie which category's mother and label
1334 * are equals to those of the calling category
1335 */
1336 $sql = "SELECT c.rowid";
1337 $sql .= " FROM ".MAIN_DB_PREFIX."categorie as c ";
1338 $sql .= " WHERE c.entity IN (".getEntity('category').")";
1339 $sql .= " AND c.type = ".((int) $type);
1340 $sql .= " AND c.fk_parent = ".((int) $this->fk_parent);
1341 $sql .= " AND c.label = '".$this->db->escape($this->label)."'";
1342
1343 dol_syslog(get_class($this)."::already_exists", LOG_DEBUG);
1344 $resql = $this->db->query($sql);
1345 if ($resql) {
1346 if ($this->db->num_rows($resql) > 0) { // Checking for empty resql
1347 $obj = $this->db->fetch_array($resql);
1348 /* If object called create, obj cannot have is id.
1349 * If object called update, he mustn't have the same label as an other category for this mother.
1350 * So if the result have the same id, update is not for label, and if result have an other one,
1351 * update may be for label.
1352 */
1353 if ($obj[0] > 0 && $obj[0] != $this->id) {
1354 dol_syslog(get_class($this)."::already_exists category with name=".$this->label." and parent ".$this->fk_parent." exists: rowid=".$obj[0]." current_id=".$this->id, LOG_DEBUG);
1355 return 1;
1356 }
1357 }
1358 dol_syslog(get_class($this)."::already_exists no category with same name=".$this->label." and same parent ".$this->fk_parent." than category id=".$this->id, LOG_DEBUG);
1359 return 0;
1360 } else {
1361 $this->error = $this->db->error();
1362 return -1;
1363 }
1364 }
1365
1366
1367 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1378 public function print_all_ways($sep = '&gt;&gt;', $url = '', $nocolor = 0, $addpicto = 0)
1379 {
1380 // phpcs:enable
1381 $ways = array();
1382
1383 $allways = $this->get_all_ways(); // Load array of categories
1384 foreach ($allways as $way) {
1385 $w = array();
1386 $i = 0;
1387 $forced_color = '';
1388 foreach ($way as $cat) {
1389 $i++;
1390
1391 if (empty($nocolor)) {
1392 $forced_color = 'colortoreplace';
1393 if ($i == count($way)) { // Last category in hierarchy
1394 // Check contrast with background and correct text color
1395 $forced_color = 'categtextwhite';
1396 if ($cat->color) {
1397 if (colorIsLight($cat->color)) {
1398 $forced_color = 'categtextblack';
1399 }
1400 }
1401 }
1402 }
1403
1404 if ($url == '') {
1405 $link = '<a href="'.DOL_URL_ROOT.'/categories/viewcat.php?id='.$cat->id.'&type='.$cat->type.'" class="'.$forced_color.'">';
1406 $linkend = '</a>';
1407 $w[] = $link.(($addpicto && $i == 1) ? img_object('', 'category', 'class="paddingright"') : '').$cat->label.$linkend;
1408 } elseif ($url == 'none') {
1409 $link = '<span class="'.$forced_color.'">';
1410 $linkend = '</span>';
1411 $w[] = $link.(($addpicto && $i == 1) ? img_object('', 'category', 'class="paddingright"') : '').$cat->label.$linkend;
1412 } else {
1413 $w[] = '<a class="'.$forced_color.'" href="'.DOL_URL_ROOT.'/'.$url.'?catid='.$cat->id.'">'.($addpicto ? img_object('', 'category') : '').$cat->label.'</a>';
1414 }
1415 }
1416 $newcategwithpath = preg_replace('/colortoreplace/', $forced_color, implode('<span class="inline-block valignmiddle paddingleft paddingright '.$forced_color.'">'.$sep.'</span>', $w));
1417
1418 $ways[] = $newcategwithpath;
1419 }
1420
1421 return $ways;
1422 }
1423
1424
1425 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1431 public function get_meres()
1432 {
1433 // phpcs:enable
1434 $parents = array();
1435
1436 $sql = "SELECT fk_parent FROM ".MAIN_DB_PREFIX."categorie";
1437 $sql .= " WHERE rowid = ".((int) $this->id);
1438
1439 $res = $this->db->query($sql);
1440
1441 if ($res) {
1442 while ($rec = $this->db->fetch_array($res)) {
1443 if ($rec['fk_parent'] > 0) {
1444 $cat = new Categorie($this->db);
1445 $cat->fetch($rec['fk_parent']);
1446 $parents[] = $cat;
1447 }
1448 }
1449 return $parents;
1450 } else {
1451 dol_print_error($this->db);
1452 return -1;
1453 }
1454 }
1455
1456 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1463 public function get_all_ways()
1464 {
1465 // phpcs:enable
1466 $ways = array();
1467
1468 $parents = $this->get_meres();
1469 if (is_array($parents)) {
1470 foreach ($parents as $parent) {
1471 $allways = $parent->get_all_ways();
1472 foreach ($allways as $way) {
1473 $w = $way;
1474 $w[] = $this;
1475 $ways[] = $w;
1476 }
1477 }
1478 }
1479
1480 if (count($ways) == 0) {
1481 $ways[0][0] = $this;
1482 }
1483
1484 return $ways;
1485 }
1486
1497 public function containing($id, $type, $mode = 'object')
1498 {
1499 $cats = array();
1500
1501 if (is_numeric($type)) {
1502 $type = Categorie::$MAP_ID_TO_CODE[$type];
1503 }
1504
1505 if ($type === Categorie::TYPE_BANK_LINE) { // TODO Remove this with standard category code after migration of llx_bank_categ into llx_categorie
1506 // Load bank categories
1507 $sql = "SELECT c.label, c.rowid";
1508 $sql .= " FROM ".MAIN_DB_PREFIX."bank_class as a, ".MAIN_DB_PREFIX."bank_categ as c";
1509 $sql .= " WHERE a.lineid=".((int) $id)." AND a.fk_categ = c.rowid";
1510 $sql .= " AND c.entity IN (".getEntity('category').")";
1511 $sql .= " ORDER BY c.label";
1512
1513 $res = $this->db->query($sql);
1514 if ($res) {
1515 while ($obj = $this->db->fetch_object($res)) {
1516 if ($mode == 'id') {
1517 $cats[] = $obj->rowid;
1518 } elseif ($mode == 'label') {
1519 $cats[] = $obj->label;
1520 } else {
1521 $cat = new Categorie($this->db);
1522 $cat->id = $obj->rowid;
1523 $cat->label = $obj->label;
1524 $cats[] = $cat;
1525 }
1526 }
1527 } else {
1528 dol_print_error($this->db);
1529 return -1;
1530 }
1531 } else {
1532 $sql = "SELECT ct.fk_categorie, c.label, c.rowid";
1533 $sql .= " FROM ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type])." as ct, ".MAIN_DB_PREFIX."categorie as c";
1534 $sql .= " WHERE ct.fk_categorie = c.rowid AND ct.fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = ".(int) $id;
1535 // This seems useless because the table already contains id of category of 1 unique type. So commented.
1536 // So now it works also with external added categories.
1537 //$sql .= " AND c.type = ".((int) $this->MAP_ID[$type]);
1538 $sql .= " AND c.entity IN (".getEntity('category').")";
1539
1540 $res = $this->db->query($sql);
1541 if ($res) {
1542 while ($obj = $this->db->fetch_object($res)) {
1543 if ($mode == 'id') {
1544 $cats[] = $obj->rowid;
1545 } elseif ($mode == 'label') {
1546 $cats[] = $obj->label;
1547 } else {
1548 $cat = new Categorie($this->db);
1549 $cat->fetch($obj->fk_categorie);
1550 $cats[] = $cat;
1551 }
1552 }
1553 } else {
1554 dol_print_error($this->db);
1555 return -1;
1556 }
1557 }
1558
1559 return $cats;
1560 }
1561
1573 public function rechercher($id, $nom, $type, $exact = false, $case = false)
1574 {
1575 // Deprecation warning
1576 if (is_numeric($type)) {
1577 dol_syslog(__METHOD__.': using numeric types is deprecated.', LOG_WARNING);
1578 }
1579
1580 $cats = array();
1581
1582 // For backward compatibility
1583 if (is_numeric($type)) {
1584 // We want to reverse lookup
1585 $map_type = array_flip($this->MAP_ID);
1586 $type = $map_type[$type];
1587 dol_syslog(get_class($this)."::rechercher(): numeric types are deprecated, please use string instead", LOG_WARNING);
1588 }
1589
1590 // Generation requete recherche
1591 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
1592 $sql .= " WHERE type = ".((int) $this->MAP_ID[$type]);
1593 $sql .= " AND entity IN (".getEntity('category').")";
1594 if ($nom) {
1595 if (!$exact) {
1596 $nom = '%'.$this->db->escape(str_replace('*', '%', $nom)).'%';
1597 }
1598 if (!$case) {
1599 $sql .= " AND label LIKE '".$this->db->escape($nom)."'";
1600 } else {
1601 $sql .= " AND label LIKE BINARY '".$this->db->escape($nom)."'";
1602 }
1603 }
1604 if ($id) {
1605 $sql .= " AND rowid = ".((int) $id);
1606 }
1607
1608 $res = $this->db->query($sql);
1609 if ($res) {
1610 while ($rec = $this->db->fetch_array($res)) {
1611 $cat = new Categorie($this->db);
1612 $cat->fetch($rec['rowid']);
1613 $cats[] = $cat;
1614 }
1615
1616 return $cats;
1617 } else {
1618 $this->error = $this->db->error().' sql='.$sql;
1619 return -1;
1620 }
1621 }
1622
1629 public function getTooltipContentArray($params)
1630 {
1631 global $langs;
1632
1633 $langs->load('categories');
1634
1635 $datas = [];
1636
1637 $datas['label'] = $langs->trans("ShowCategory").': '.($this->ref ? $this->ref : $this->label);
1638
1639 return $datas;
1640 }
1641
1652 public function getNomUrl($withpicto = 0, $option = '', $maxlength = 0, $moreparam = '')
1653 {
1654 global $langs, $hookmanager;
1655
1656 $result = '';
1657 $params = [
1658 'id' => $this->id,
1659 'objecttype' => $this->element,
1660 'option' => $option,
1661 ];
1662 $classfortooltip = 'classfortooltip';
1663 $dataparams = '';
1664 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1665 $classfortooltip = 'classforajaxtooltip';
1666 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1667 $label = '';
1668 } else {
1669 $label = implode($this->getTooltipContentArray($params));
1670 }
1671
1672 // Check contrast with background and correct text color
1673 $forced_color = 'categtextwhite';
1674 if ($this->color) {
1675 if (colorIsLight($this->color)) {
1676 $forced_color = 'categtextblack';
1677 }
1678 }
1679 $link = '<a href="'.DOL_URL_ROOT.'/categories/viewcat.php?id='.$this->id.'&type='.$this->type.$moreparam.'&backtopage='.urlencode($_SERVER['PHP_SELF'].($moreparam ? '?'.$moreparam : ''));
1680 $link .= '"'.$dataparams;
1681 $link .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1682 $link .= ' class="'.$classfortooltip.' '.$forced_color.'">';
1683 $linkend = '</a>';
1684
1685 $picto = 'category';
1686
1687
1688 if ($withpicto) {
1689 $result .= ($link.img_object($label, $picto, $dataparams.' class="'.$classfortooltip.'"').$linkend);
1690 }
1691 if ($withpicto && $withpicto != 2) {
1692 $result .= ' ';
1693 }
1694 if ($withpicto != 2) {
1695 $result .= $link.dol_trunc(($this->ref ? $this->ref : $this->label), $maxlength).$linkend;
1696 }
1697 global $action;
1698 $hookmanager->initHooks(array($this->element . 'dao'));
1699 $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1700 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1701 if ($reshook > 0) {
1702 $result = $hookmanager->resPrint;
1703 } else {
1704 $result .= $hookmanager->resPrint;
1705 }
1706 return $result;
1707 }
1708
1709
1710 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1718 public function add_photo($sdir, $file)
1719 {
1720 // phpcs:enable
1721 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1722
1723 $dir = $sdir.'/'.get_exdir($this->id, 2, 0, 0, $this, 'category').$this->id."/";
1724 $dir .= "photos/";
1725
1726 if (!file_exists($dir)) {
1727 dol_mkdir($dir);
1728 }
1729
1730 if (file_exists($dir)) {
1731 if (is_array($file['name']) && count($file['name']) > 0) {
1732 $nbfile = count($file['name']);
1733 for ($i = 0; $i <= $nbfile; $i++) {
1734 $originImage = $dir.$file['name'][$i];
1735
1736 // Cree fichier en taille origine
1737 dol_move_uploaded_file($file['tmp_name'][$i], $originImage, 1, 0, 0);
1738
1739 if (file_exists($originImage)) {
1740 // Create thumbs
1741 $this->addThumbs($originImage);
1742 }
1743 }
1744 } else {
1745 $originImage = $dir.$file['name'];
1746
1747 // Cree fichier en taille origine
1748 dol_move_uploaded_file($file['tmp_name'], $originImage, 1, 0, 0);
1749
1750 if (file_exists($originImage)) {
1751 // Create thumbs
1752 $this->addThumbs($originImage);
1753 }
1754 }
1755 }
1756 }
1757
1758 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1766 public function liste_photos($dir, $nbmax = 0)
1767 {
1768 // phpcs:enable
1769 include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1770
1771 $nbphoto = 0;
1772 $tabobj = array();
1773
1774 $dirthumb = $dir.'thumbs/';
1775
1776 if (file_exists($dir)) {
1777 $handle = opendir($dir);
1778 if (is_resource($handle)) {
1779 while (($file = readdir($handle)) !== false) {
1780 if (dol_is_file($dir.$file) && preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i', $dir.$file)) {
1781 $nbphoto++;
1782 $photo = $file;
1783
1784 // On determine nom du fichier vignette
1785 $photo_vignette = '';
1786 if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i', $photo, $regs)) {
1787 $photo_vignette = preg_replace('/'.$regs[0].'/i', '', $photo).'_small'.$regs[0];
1788 }
1789
1790 // Objet
1791 $obj = array();
1792 $obj['photo'] = $photo;
1793 if ($photo_vignette && is_file($dirthumb.$photo_vignette)) {
1794 $obj['photo_vignette'] = 'thumbs/'.$photo_vignette;
1795 } else {
1796 $obj['photo_vignette'] = "";
1797 }
1798
1799 $tabobj[$nbphoto - 1] = $obj;
1800
1801 // On continue ou on arrete de boucler
1802 if ($nbmax && $nbphoto >= $nbmax) {
1803 break;
1804 }
1805 }
1806 }
1807
1808 closedir($handle);
1809 }
1810 }
1811
1812 return $tabobj;
1813 }
1814
1815 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1822 public function delete_photo($file)
1823 {
1824 // phpcs:enable
1825 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1826
1827 $dir = dirname($file).'/'; // Chemin du dossier contenant l'image d'origine
1828 $dirthumb = $dir.'/thumbs/'; // Chemin du dossier contenant la vignette
1829 $filename = preg_replace('/'.preg_quote($dir, '/').'/i', '', $file); // Nom du fichier
1830
1831 // On efface l'image d'origine
1832 dol_delete_file($file, 1);
1833
1834 // Si elle existe, on efface la vignette
1835 if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i', $filename, $regs)) {
1836 $photo_vignette = preg_replace('/'.$regs[0].'/i', '', $filename).'_small'.$regs[0];
1837 if (file_exists($dirthumb.$photo_vignette)) {
1838 dol_delete_file($dirthumb.$photo_vignette, 1);
1839 }
1840 }
1841 }
1842
1843 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1850 public function get_image_size($file)
1851 {
1852 // phpcs:enable
1853 $infoImg = getimagesize($file); // Recuperation des infos de l'image
1854 $this->imgWidth = $infoImg[0]; // Largeur de l'image
1855 $this->imgHeight = $infoImg[1]; // Hauteur de l'image
1856 }
1857
1865 public function setMultiLangs($user)
1866 {
1867 global $langs;
1868
1869 $langs_available = $langs->get_available_languages();
1870 $current_lang = $langs->getDefaultLang();
1871
1872 foreach ($langs_available as $key => $value) {
1873 $sql = "SELECT rowid";
1874 $sql .= " FROM ".MAIN_DB_PREFIX."categorie_lang";
1875 $sql .= " WHERE fk_category=".((int) $this->id);
1876 $sql .= " AND lang = '".$this->db->escape($key)."'";
1877
1878 $result = $this->db->query($sql);
1879
1880 if ($key == $current_lang) {
1881 if ($this->db->num_rows($result)) { // si aucune ligne dans la base
1882 $sql2 = "UPDATE ".MAIN_DB_PREFIX."categorie_lang";
1883 $sql2 .= " SET label = '".$this->db->escape($this->label)."',";
1884 $sql2 .= " description = '".$this->db->escape($this->description)."'";
1885 $sql2 .= " WHERE fk_category = ".((int) $this->id)." AND lang = '".$this->db->escape($key)."'";
1886 } else {
1887 $sql2 = "INSERT INTO ".MAIN_DB_PREFIX."categorie_lang (fk_category, lang, label, description)";
1888 $sql2 .= " VALUES(".((int) $this->id).", '".$this->db->escape($key)."', '".$this->db->escape($this->label)."'";
1889 $sql2 .= ", '".$this->db->escape($this->multilangs["$key"]["description"])."')";
1890 }
1891 dol_syslog(get_class($this).'::setMultiLangs', LOG_DEBUG);
1892 if (!$this->db->query($sql2)) {
1893 $this->error = $this->db->lasterror();
1894 return -1;
1895 }
1896 } elseif (isset($this->multilangs["$key"])) {
1897 if ($this->db->num_rows($result)) { // si aucune ligne dans la base
1898 $sql2 = "UPDATE ".MAIN_DB_PREFIX."categorie_lang";
1899 $sql2 .= " SET label='".$this->db->escape($this->multilangs["$key"]["label"])."',";
1900 $sql2 .= " description='".$this->db->escape($this->multilangs["$key"]["description"])."'";
1901 $sql2 .= " WHERE fk_category=".((int) $this->id)." AND lang='".$this->db->escape($key)."'";
1902 } else {
1903 $sql2 = "INSERT INTO ".MAIN_DB_PREFIX."categorie_lang (fk_category, lang, label, description)";
1904 $sql2 .= " VALUES(".((int) $this->id).", '".$this->db->escape($key)."', '".$this->db->escape($this->multilangs["$key"]["label"])."'";
1905 $sql2 .= ",'".$this->db->escape($this->multilangs["$key"]["description"])."')";
1906 }
1907
1908 // on ne sauvegarde pas des champs vides
1909 if ($this->multilangs["$key"]["label"] || $this->multilangs["$key"]["description"] || $this->multilangs["$key"]["note"]) {
1910 dol_syslog(get_class($this).'::setMultiLangs', LOG_DEBUG);
1911 }
1912 if (!$this->db->query($sql2)) {
1913 $this->error = $this->db->lasterror();
1914 return -1;
1915 }
1916 }
1917 }
1918
1919 // Call trigger
1920 $result = $this->call_trigger('CATEGORY_SET_MULTILANGS', $user);
1921 if ($result < 0) {
1922 $this->error = $this->db->lasterror();
1923 return -1;
1924 }
1925 // End call triggers
1926
1927 return 1;
1928 }
1929
1935 public function getMultiLangs()
1936 {
1937 global $langs;
1938
1939 $current_lang = $langs->getDefaultLang();
1940
1941 $sql = "SELECT lang, label, description";
1942 $sql .= " FROM ".MAIN_DB_PREFIX."categorie_lang";
1943 $sql .= " WHERE fk_category=".((int) $this->id);
1944
1945 $result = $this->db->query($sql);
1946 if ($result) {
1947 while ($obj = $this->db->fetch_object($result)) {
1948 //print 'lang='.$obj->lang.' current='.$current_lang.'<br>';
1949 if ($obj->lang == $current_lang) { // si on a les traduct. dans la langue courante on les charge en infos principales.
1950 $this->label = $obj->label;
1951 $this->description = $obj->description;
1952 }
1953 $this->multilangs["$obj->lang"]["label"] = $obj->label;
1954 $this->multilangs["$obj->lang"]["description"] = $obj->description;
1955 }
1956 return 1;
1957 } else {
1958 $this->error = $langs->trans("Error")." : ".$this->db->error()." - ".$sql;
1959 return -1;
1960 }
1961 }
1962
1969 public function getLibStatut($mode)
1970 {
1971 return '';
1972 }
1973
1974
1982 public function initAsSpecimen()
1983 {
1984 dol_syslog(get_class($this)."::initAsSpecimen");
1985
1986 // Initialise parametres
1987 $this->id = 0;
1988 $this->fk_parent = 0;
1989 $this->label = 'SPECIMEN';
1990 $this->specimen = 1;
1991 $this->description = 'This is a description';
1992 $this->socid = 1;
1993 $this->type = self::TYPE_PRODUCT;
1994 }
1995
2004 public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
2005 {
2006 $tables = array(
2007 'categorie_societe'
2008 );
2009
2010 return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables, 1);
2011 }
2012
2021 public static function getFilterJoinQuery($type, $rowIdName)
2022 {
2023 if ($type == 'bank_account') {
2024 $type = 'account';
2025 }
2026
2027 return " LEFT JOIN ".MAIN_DB_PREFIX."categorie_".$type." as cp ON ".$rowIdName." = cp.fk_".$type;
2028 }
2029
2039 public static function getFilterSelectQuery($type, $rowIdName, $searchList)
2040 {
2041 if ($type == 'bank_account') {
2042 $type = 'account';
2043 }
2044 if ($type == 'customer') {
2045 $type = 'societe';
2046 }
2047 if ($type == 'supplier') {
2048 $type = 'fournisseur';
2049 }
2050
2051 if (empty($searchList) && !is_array($searchList)) {
2052 return "";
2053 }
2054
2055 $searchCategorySqlList = array();
2056 foreach ($searchList as $searchCategory) {
2057 if (intval($searchCategory) == -2) {
2058 $searchCategorySqlList[] = " cp.fk_categorie IS NULL";
2059 } elseif (intval($searchCategory) > 0) {
2060 $searchCategorySqlList[] = " ".$rowIdName." IN (SELECT fk_".$type." FROM ".MAIN_DB_PREFIX."categorie_".$type." WHERE fk_categorie = ".((int) $searchCategory).")";
2061 }
2062 }
2063
2064 if (!empty($searchCategorySqlList)) {
2065 return " AND (".implode(' AND ', $searchCategorySqlList).")";
2066 } else {
2067 return "";
2068 }
2069 }
2070
2076 public function countNbOfCategories()
2077 {
2078 dol_syslog(get_class($this)."::count_all_categories", LOG_DEBUG);
2079 $sql = "SELECT COUNT(rowid) FROM ".MAIN_DB_PREFIX."categorie";
2080 $sql .= " WHERE entity IN (".getEntity('category').")";
2081
2082 $res = $this->db->query($sql);
2083 if ($res) {
2084 $obj = $this->db->fetch_object($res);
2085 return $obj->count;
2086 } else {
2087 dol_print_error($this->db);
2088 return -1;
2089 }
2090 }
2091}
$object ref
Definition info.php:78
Class to manage categories.
setMultiLangs($user)
Update ou cree les traductions des infos produits.
getListForItem($id, $type='customer', $sortfield="s.rowid", $sortorder='ASC', $limit=0, $page=0)
List categories of an element id.
get_image_size($file)
Load size of image file.
getObjectsInCateg($type, $onlyids=0, $limit=0, $offset=0, $sortfield='', $sortorder='ASC', $filter=array(), $filtermode='AND')
Return list of fetched instance of elements having this category.
load_motherof()
Load the array this->motherof that is array(id_son=>id_parent, ...)
getLibStatut($mode)
Return label of contact status.
delete_photo($file)
Efface la photo de la categorie et sa vignette.
containing($id, $type, $mode='object')
Return list of categories (object instances or labels) linked to element of id $id and type $type Sho...
getTooltipContentArray($params)
getTooltipContentArray
countNbOfCategories()
Count all categories.
del_type($obj, $type)
Delete object from category.
buildPathFromId($id_categ, $protection=1000)
For category id_categ and its childs available in this->cats, define property fullpath and fulllabel.
static getFilterSelectQuery($type, $rowIdName, $searchList)
Return the addtional SQL SELECT query for filtering a list by a category.
rechercher($id, $nom, $type, $exact=false, $case=false)
Returns categories whose id or name match add wildcards in the name unless $exact = true.
getMultiLangs()
Load array this->multilangs.
already_exists()
Check if no category with same label already exists for this cat's parent or root and for this cat's ...
get_filles()
Return direct childs id of a category into an array.
initAsSpecimen()
Initialise an instance with random values.
get_all_categories($type=null, $parent=false)
Returns all categories.
static getFilterJoinQuery($type, $rowIdName)
Return the addtional SQL JOIN query for filtering a list by a category.
containsObject($type, $object_id)
Check for the presence of an object in a category.
get_main_categories($type=null)
Returns the top level categories (which are not child)
__construct($db)
Constructor.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
getMapList()
Get map list.
get_full_arbo($type, $markafterid=0, $include=0)
Rebuilding the category tree as an array Return an array of table('id','id_mere',....
get_meres()
Returns an array containing the list of parent categories.
add_type($obj, $type='')
Link an object to the category.
create($user)
Add category into database.
update(User $user)
Update category.
liste_photos($dir, $nbmax=0)
Return tableau de toutes les photos de la categorie.
get_all_ways()
Returns in a table all possible paths to get to the category starting with the major categories repre...
print_all_ways($sep='&gt;&gt;', $url='', $nocolor=0, $addpicto=0)
Returns the path of the category, with the names of the categories separated by $sep (" >> " by defau...
getNomUrl($withpicto=0, $option='', $maxlength=0, $moreparam='')
Return name and link of category (with picto) Use ->id, ->ref, ->label, ->color.
add_photo($sdir, $file)
Deplace fichier uploade sous le nom $file dans le repertoire sdir.
fetch($id, $label='', $type=null, $ref_ext='')
Load category into memory from database.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
deleteExtraFields()
Delete all extra fields values for the current object.
addThumbs($file)
Build thumb.
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Class to manage Dolibarr database access.
Class to manage Dolibarr users.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $varfiles='addedfile', $upload_dir='')
Make control on an uploaded file from an GUI page and move it to final destination.
dol_is_file($pathoffile)
Return if path is a file.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by second index function, which produces ascending (default) or descending output...
colorIsLight($stringcolor)
Return true if the color is light.
sanitizeVal($out='', $check='alphanohtml', $filter=null, $options=null)
Return a sanitized or empty value after checking value against a rule.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:120