dolibarr 20.0.4
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-2024 Frédéric France <frederic.france@free.fr>
14 * Copyright (C) 2023-2024 Benjamin Falière <benjamin.faliere@altairis.fr>
15 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <https://www.gnu.org/licenses/>.
29 */
30
37require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
38require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
39require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php';
40require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
41require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
42require_once DOL_DOCUMENT_ROOT.'/knowledgemanagement/class/knowledgerecord.class.php';
43
44
49{
50 // Categories types (we use string because we want to accept any modules/types in a future)
51 const TYPE_PRODUCT = 'product';
52 const TYPE_SUPPLIER = 'supplier';
53 const TYPE_CUSTOMER = 'customer';
54 const TYPE_MEMBER = 'member';
55 const TYPE_CONTACT = 'contact';
56 const TYPE_USER = 'user';
57 const TYPE_PROJECT = 'project';
58 const TYPE_ACCOUNT = 'bank_account';
59 const TYPE_BANK_LINE = 'bank_line';
60 const TYPE_WAREHOUSE = 'warehouse';
61 const TYPE_ACTIONCOMM = 'actioncomm';
62 const TYPE_WEBSITE_PAGE = 'website_page';
63 const TYPE_TICKET = 'ticket';
64 const TYPE_KNOWLEDGEMANAGEMENT = 'knowledgemanagement';
65
69 public $picto = 'category';
70
71
75 protected $MAP_ID = array(
76 'product' => 0,
77 'supplier' => 1,
78 'customer' => 2,
79 'member' => 3,
80 'contact' => 4,
81 'bank_account' => 5,
82 'project' => 6,
83 'user' => 7,
84 'bank_line' => 8,
85 'warehouse' => 9,
86 'actioncomm' => 10,
87 'website_page' => 11,
88 'ticket' => 12,
89 'knowledgemanagement' => 13
90 );
91
97 public static $MAP_ID_TO_CODE = array(
98 0 => 'product',
99 1 => 'supplier',
100 2 => 'customer',
101 3 => 'member',
102 4 => 'contact',
103 5 => 'bank_account',
104 6 => 'project',
105 7 => 'user',
106 8 => 'bank_line',
107 9 => 'warehouse',
108 10 => 'actioncomm',
109 11 => 'website_page',
110 12 => 'ticket',
111 13 => 'knowledgemanagement'
112 );
113
119 public $MAP_CAT_FK = array(
120 'customer' => 'soc',
121 'supplier' => 'soc',
122 'contact' => 'socpeople',
123 'bank_account' => 'account',
124 );
125
131 public $MAP_CAT_TABLE = array(
132 'customer' => 'societe',
133 'supplier' => 'fournisseur',
134 'bank_account' => 'account',
135 );
136
142 public $MAP_OBJ_CLASS = array(
143 'product' => 'Product',
144 'customer' => 'Societe',
145 'supplier' => 'Fournisseur',
146 'member' => 'Adherent',
147 'contact' => 'Contact',
148 'user' => 'User',
149 'account' => 'Account', // old for bank account
150 'bank_account' => 'Account',
151 'project' => 'Project',
152 'warehouse' => 'Entrepot',
153 'actioncomm' => 'ActionComm',
154 'website_page' => 'WebsitePage',
155 'ticket' => 'Ticket',
156 'knowledgemanagement' => 'KnowledgeRecord'
157 );
158
164 public static $MAP_TYPE_TITLE_AREA = array(
165 'product' => 'ProductsCategoriesArea',
166 'customer' => 'CustomersCategoriesArea',
167 'supplier' => 'SuppliersCategoriesArea',
168 'member' => 'MembersCategoriesArea',
169 'contact' => 'ContactsCategoriesArea',
170 'user' => 'UsersCategoriesArea',
171 'account' => 'AccountsCategoriesArea', // old for bank account
172 'bank_account' => 'AccountsCategoriesArea',
173 'project' => 'ProjectsCategoriesArea',
174 'warehouse' => 'StocksCategoriesArea',
175 'actioncomm' => 'ActioncommCategoriesArea',
176 'website_page' => 'WebsitePageCategoriesArea'
177 );
178
183 public $MAP_OBJ_TABLE = array(
184 'customer' => 'societe',
185 'supplier' => 'societe',
186 'member' => 'adherent',
187 'contact' => 'socpeople',
188 'account' => 'bank_account', // old for bank account
189 'project' => 'projet',
190 'warehouse' => 'entrepot',
191 'knowledgemanagement' => 'knowledgemanagement_knowledgerecord'
192 );
193
197 public $element = 'category';
198
202 public $table_element = 'categorie';
203
207 public $fk_parent;
208
212 public $label;
213
217 public $description;
218
222 public $color;
223
227 public $position;
228
232 public $visible;
233
237 public $socid;
238
256 public $type;
257
261 public $cats = array();
262
266 public $motherof = array();
267
271 public $childs = array();
272
276 public $multilangs;
277
281 public $imgWidth;
282
286 public $imgHeight;
287
316 public $fields = array(
317 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'index' => 1, 'position' => 1, 'comment' => 'Id'),
318 'entity' => array('type' => 'integer', 'label' => 'Entity', 'enabled' => 1, 'visible' => 0, 'default' => '1', 'notnull' => 1, 'index' => 1, 'position' => 5),
319 'label' => array('type' => 'varchar(255)', 'label' => 'Label', 'enabled' => 1, 'visible' => 1, 'showoncombobox' => 1, 'position' => 15, 'csslist' => 'tdoverflowmax250'),
320 );
321
327 public function __construct($db)
328 {
329 global $hookmanager;
330
331 $this->db = $db;
332
333 if (is_object($hookmanager)) {
334 $hookmanager->initHooks(array('category'));
335 $parameters = array();
336 $reshook = $hookmanager->executeHooks('constructCategory', $parameters, $this); // Note that $action and $object may have been modified by some hooks
337 if ($reshook >= 0 && !empty($hookmanager->resArray)) {
338 foreach ($hookmanager->resArray as $mapList) {
339 $mapId = $mapList['id'];
340 $mapCode = $mapList['code'];
341 self::$MAP_ID_TO_CODE[$mapId] = $mapCode;
342 $this->MAP_ID[$mapCode] = $mapId;
343 $this->MAP_CAT_FK[$mapCode] = isset($mapList['cat_fk']) ? $mapList['cat_fk'] : null;
344 $this->MAP_CAT_TABLE[$mapCode] = isset($mapList['cat_table']) ? $mapList['cat_table'] : null;
345 $this->MAP_OBJ_CLASS[$mapCode] = $mapList['obj_class'];
346 $this->MAP_OBJ_TABLE[$mapCode] = $mapList['obj_table'];
347 }
348 }
349 }
350 }
351
357 public function getMapList()
358 {
359 $mapList = array();
360
361 foreach ($this->MAP_ID as $mapCode => $mapId) {
362 $mapList[] = array(
363 'id' => $mapId,
364 'code' => $mapCode,
365 'cat_fk' => (empty($this->MAP_CAT_FK[$mapCode]) ? $mapCode : $this->MAP_CAT_FK[$mapCode]),
366 'cat_table' => (empty($this->MAP_CAT_TABLE[$mapCode]) ? $mapCode : $this->MAP_CAT_TABLE[$mapCode]),
367 'obj_class' => (empty($this->MAP_OBJ_CLASS[$mapCode]) ? $mapCode : $this->MAP_OBJ_CLASS[$mapCode]),
368 'obj_table' => (empty($this->MAP_OBJ_TABLE[$mapCode]) ? $mapCode : $this->MAP_OBJ_TABLE[$mapCode])
369 );
370 }
371
372 return $mapList;
373 }
374
384 public function fetch($id, $label = '', $type = null, $ref_ext = '')
385 {
386 // Check parameters
387 if (empty($id) && empty($label) && empty($ref_ext)) {
388 $this->error = "No category to search for";
389 return -1;
390 }
391 if (!is_null($type) && !is_numeric($type)) {
392 $type = $this->MAP_ID[$type];
393 }
394
395 $sql = "SELECT rowid, fk_parent, entity, label, description, color, position, fk_soc, visible, type, ref_ext";
396 $sql .= ", date_creation, tms, fk_user_creat, fk_user_modif";
397 $sql .= " FROM ".MAIN_DB_PREFIX."categorie";
398 if ($id) {
399 $sql .= " WHERE rowid = ".((int) $id);
400 } elseif (!empty($ref_ext)) {
401 $sql .= " WHERE ref_ext LIKE '".$this->db->escape($ref_ext)."'";
402 } else {
403 $sql .= " WHERE label = '".$this->db->escape($label)."' AND entity IN (".getEntity('category').")";
404 if (!is_null($type)) {
405 $sql .= " AND type = ".((int) $type);
406 }
407 }
408
409 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
410 $resql = $this->db->query($sql);
411 if ($resql) {
412 if ($this->db->num_rows($resql) > 0 && $res = $this->db->fetch_array($resql)) {
413 $this->id = $res['rowid'];
414 //$this->ref = $res['rowid'];
415 $this->fk_parent = (int) $res['fk_parent'];
416 $this->label = $res['label'];
417 $this->description = $res['description'];
418 $this->color = $res['color'];
419 $this->position = $res['position'];
420 $this->socid = (int) $res['fk_soc'];
421 $this->visible = (int) $res['visible'];
422 $this->type = $res['type'];
423 $this->ref_ext = $res['ref_ext'];
424 $this->entity = (int) $res['entity'];
425 $this->date_creation = $this->db->jdate($res['date_creation']);
426 $this->date_modification = $this->db->jdate($res['tms']);
427 $this->user_creation_id = (int) $res['fk_user_creat'];
428 $this->user_modification_id = (int) $res['fk_user_modif'];
429
430 // Retrieve all extrafield
431 // fetch optionals attributes and labels
432 $this->fetch_optionals();
433
434 $this->db->free($resql);
435
436 // multilangs
437 if (getDolGlobalInt('MAIN_MULTILANGS')) {
438 $this->getMultiLangs();
439 }
440
441 return 1;
442 } else {
443 $this->error = "No category found";
444 return 0;
445 }
446 } else {
447 dol_print_error($this->db);
448 $this->error = $this->db->lasterror;
449 $this->errors[] = $this->db->lasterror;
450 return -1;
451 }
452 }
453
464 public function create($user, $notrigger = 0)
465 {
466 global $conf, $langs, $hookmanager;
467 $langs->load('categories');
468
469 $type = $this->type;
470
471 if (!is_numeric($type)) {
472 $type = $this->MAP_ID[$type];
473 }
474
475 $error = 0;
476
477 dol_syslog(get_class($this).'::create', LOG_DEBUG);
478
479 // Clean parameters
480 $this->label = trim($this->label);
481 $this->description = trim($this->description);
482 $this->color = trim($this->color);
483 $this->position = (int) $this->position;
484 $this->import_key = trim($this->import_key);
485 $this->ref_ext = trim($this->ref_ext);
486 if (empty($this->visible)) {
487 $this->visible = 0;
488 }
489 $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
490
491 if ($this->already_exists()) {
492 $this->error = $langs->trans("ImpossibleAddCat", $this->label);
493 $this->error .= " : ".$langs->trans("CategoryExistsAtSameLevel");
494 dol_syslog($this->error, LOG_WARNING);
495 return -4;
496 }
497
498 $this->db->begin();
499 $now = dol_now();
500 $sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie (";
501 $sql .= "fk_parent,";
502 $sql .= " label,";
503 $sql .= " description,";
504 $sql .= " color,";
505 $sql .= " position,";
506 if (getDolGlobalString('CATEGORY_ASSIGNED_TO_A_CUSTOMER')) {
507 $sql .= "fk_soc,";
508 }
509 $sql .= " visible,";
510 $sql .= " type,";
511 $sql .= " import_key,";
512 $sql .= " ref_ext,";
513 $sql .= " entity,";
514 $sql .= " date_creation,";
515 $sql .= " fk_user_creat";
516 $sql .= ") VALUES (";
517 $sql .= (int) $this->fk_parent.",";
518 $sql .= "'".$this->db->escape($this->label)."', ";
519 $sql .= "'".$this->db->escape($this->description)."', ";
520 $sql .= "'".$this->db->escape($this->color)."', ";
521 $sql .= (int) $this->position.",";
522 if (getDolGlobalString('CATEGORY_ASSIGNED_TO_A_CUSTOMER')) {
523 $sql .= ($this->socid > 0 ? $this->socid : 'null').", ";
524 }
525 $sql .= "'".$this->db->escape($this->visible)."', ";
526 $sql .= ((int) $type).", ";
527 $sql .= (!empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : 'null').", ";
528 $sql .= (!empty($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : 'null').", ";
529 $sql .= (int) $conf->entity.", ";
530 $sql .= "'".$this->db->idate($now)."', ";
531 $sql .= (int) $user->id;
532 $sql .= ")";
533
534 $res = $this->db->query($sql);
535 if ($res) {
536 $id = $this->db->last_insert_id(MAIN_DB_PREFIX."categorie");
537
538 if ($id > 0) {
539 $this->id = $id;
540
541 $action = 'create';
542
543 // Actions on extra fields
544 if (!$error) {
545 $result = $this->insertExtraFields();
546 if ($result < 0) {
547 $error++;
548 }
549 }
550
551 if (!$error && !$notrigger) {
552 // Call trigger
553 $result = $this->call_trigger('CATEGORY_CREATE', $user);
554 if ($result < 0) {
555 $error++;
556 }
557 // End call triggers
558 }
559
560 if (!$error) {
561 $this->db->commit();
562 return $id;
563 } else {
564 $this->db->rollback();
565 return -3;
566 }
567 } else {
568 $this->db->rollback();
569 return -2;
570 }
571 } else {
572 $this->error = $this->db->error();
573 $this->db->rollback();
574 return -1;
575 }
576 }
577
587 public function update(User $user, $notrigger = 0)
588 {
589 global $langs;
590
591 $error = 0;
592
593 // Clean parameters
594 $this->label = trim($this->label);
595 $this->description = trim($this->description);
596 $this->ref_ext = trim($this->ref_ext);
597 $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
598 $this->visible = ($this->visible != "" ? intval($this->visible) : 0);
599
600 if ($this->already_exists()) {
601 $this->error = $langs->trans("ImpossibleUpdateCat");
602 $this->error .= " : ".$langs->trans("CategoryExistsAtSameLevel");
603 return -1;
604 }
605
606 $this->db->begin();
607
608 $sql = "UPDATE ".MAIN_DB_PREFIX."categorie";
609 $sql .= " SET label = '".$this->db->escape($this->label)."',";
610 $sql .= " description = '".$this->db->escape($this->description)."',";
611 $sql .= " ref_ext = '".$this->db->escape($this->ref_ext)."',";
612 $sql .= " color = '".$this->db->escape($this->color)."'";
613 $sql .= ", position = ".(int) $this->position;
614 if (getDolGlobalString('CATEGORY_ASSIGNED_TO_A_CUSTOMER')) {
615 $sql .= ", fk_soc = ".($this->socid > 0 ? $this->socid : 'null');
616 }
617 $sql .= ", visible = ".(int) $this->visible;
618 $sql .= ", fk_parent = ".(int) $this->fk_parent;
619 $sql .= ", fk_user_modif = ".(int) $user->id;
620 $sql .= " WHERE rowid = ".((int) $this->id);
621
622 dol_syslog(get_class($this)."::update", LOG_DEBUG);
623 if ($this->db->query($sql)) {
624 $action = 'update';
625
626 // Actions on extra fields
627 if (!$error) {
628 $result = $this->insertExtraFields();
629 if ($result < 0) {
630 $error++;
631 }
632 }
633
634 if (!$error && !$notrigger) {
635 // Call trigger
636 $result = $this->call_trigger('CATEGORY_MODIFY', $user);
637 if ($result < 0) {
638 $error++;
639 }
640 // End call triggers
641 }
642
643 if (!$error) {
644 $this->db->commit();
645 return 1;
646 } else {
647 $this->db->rollback();
648 return -1;
649 }
650 } else {
651 $this->db->rollback();
652 dol_print_error($this->db);
653 return -1;
654 }
655 }
656
664 public function delete($user, $notrigger = 0)
665 {
666 $error = 0;
667
668 // Clean parameters
669 $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
670
671 dol_syslog(get_class($this)."::remove");
672
673 $this->db->begin();
674
675 if (!$error && !$notrigger) {
676 // Call trigger
677 $result = $this->call_trigger('CATEGORY_DELETE', $user);
678 if ($result < 0) {
679 $error++;
680 }
681 // End call triggers
682 }
683
684 /* FIX #1317 : Check for child category and move up 1 level*/
685 if (!$error) {
686 $sql = "UPDATE ".MAIN_DB_PREFIX."categorie";
687 $sql .= " SET fk_parent = ".((int) $this->fk_parent);
688 $sql .= " WHERE fk_parent = ".((int) $this->id);
689
690 if (!$this->db->query($sql)) {
691 $this->error = $this->db->lasterror();
692 $error++;
693 }
694 }
695
696 $arraydelete = array(
697 'categorie_account' => 'fk_categorie',
698 'categorie_actioncomm' => 'fk_categorie',
699 'categorie_contact' => 'fk_categorie',
700 'categorie_fournisseur' => 'fk_categorie',
701 'categorie_knowledgemanagement' => array('field' => 'fk_categorie', 'enabled' => isModEnabled('knowledgemanagement')),
702 'categorie_member' => 'fk_categorie',
703 'categorie_user' => 'fk_categorie',
704 'categorie_product' => 'fk_categorie',
705 'categorie_project' => 'fk_categorie',
706 'categorie_societe' => 'fk_categorie',
707 'categorie_ticket' => array('field' => 'fk_categorie', 'enabled' => isModEnabled('ticket')),
708 'categorie_warehouse' => 'fk_categorie',
709 'categorie_website_page' => array('field' => 'fk_categorie', 'enabled' => isModEnabled('website')),
710 'bank_class' => 'fk_categ',
711 'categorie_lang' => 'fk_category',
712 'categorie' => 'rowid',
713 );
714 foreach ($arraydelete as $key => $value) {
715 if (is_array($value)) {
716 if (empty($value['enabled'])) {
717 continue;
718 }
719 $value = $value['field'];
720 }
721 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$key;
722 $sql .= " WHERE ".$value." = ".((int) $this->id);
723 if (!$this->db->query($sql)) {
724 $this->errors[] = $this->db->lasterror();
725 dol_syslog("Error sql=".$sql." ".$this->error, LOG_ERR);
726 $error++;
727 }
728 }
729
730 // Removed extrafields
731 if (!$error) {
732 $result = $this->deleteExtraFields();
733 if ($result < 0) {
734 $error++;
735 dol_syslog(get_class($this)."::delete erreur ".$this->error, LOG_ERR);
736 }
737 }
738
739 if (!$error) {
740 $this->db->commit();
741 return 1;
742 } else {
743 $this->db->rollback();
744 return -1;
745 }
746 }
747
748 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
757 public function add_type($obj, $type = '')
758 {
759 // phpcs:enable
760 global $user;
761
762 $error = 0;
763
764 if ($this->id == -1) {
765 return -2;
766 }
767
768 if (empty($type)) {
769 $type = $obj->element;
770 }
771
772 dol_syslog(get_class($this).'::add_type', LOG_DEBUG);
773
774 $this->db->begin();
775
776 $sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type]);
777 $sql .= " (fk_categorie, fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type]).")";
778 $sql .= " VALUES (".((int) $this->id).", ".((int) $obj->id).")";
779
780 if ($this->db->query($sql)) {
781 if (getDolGlobalString('CATEGORIE_RECURSIV_ADD')) {
782 $sql = 'SELECT fk_parent FROM '.MAIN_DB_PREFIX.'categorie';
783 $sql .= " WHERE rowid = ".((int) $this->id);
784
785 dol_syslog(get_class($this)."::add_type", LOG_DEBUG);
786 $resql = $this->db->query($sql);
787 if ($resql) {
788 if ($this->db->num_rows($resql) > 0) {
789 $objparent = $this->db->fetch_object($resql);
790
791 if (!empty($objparent->fk_parent)) {
792 $cat = new Categorie($this->db);
793 $cat->id = $objparent->fk_parent;
794 if (!$cat->containsObject($type, $obj->id)) {
795 $result = $cat->add_type($obj, $type);
796 if ($result < 0) {
797 $this->error = $cat->error;
798 $error++;
799 }
800 }
801 }
802 }
803 } else {
804 $error++;
805 $this->error = $this->db->lasterror();
806 }
807
808 if ($error) {
809 $this->db->rollback();
810 return -1;
811 }
812 }
813
814 // Call trigger
815 $this->context = array('linkto' => $obj); // Save object we want to link category to into category instance to provide information to trigger
816 $result = $this->call_trigger('CATEGORY_LINK', $user);
817 if ($result < 0) {
818 $error++;
819 }
820 // End call triggers
821
822 if (!$error) {
823 $this->db->commit();
824 return 1;
825 } else {
826 $this->db->rollback();
827 return -2;
828 }
829 } else {
830 $this->db->rollback();
831 if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
832 $this->error = $this->db->lasterrno();
833 return -3;
834 } else {
835 $this->error = $this->db->lasterror();
836 }
837 return -1;
838 }
839 }
840
841 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
850 public function del_type($obj, $type)
851 {
852 // phpcs:enable
853 global $user;
854
855 $error = 0;
856
857 // For backward compatibility
858 if ($type == 'societe') {
859 $type = 'customer';
860 dol_syslog(get_class($this)."::del_type(): type 'societe' is deprecated, please use 'customer' instead", LOG_WARNING);
861 } elseif ($type == 'fournisseur') {
862 $type = 'supplier';
863 dol_syslog(get_class($this)."::del_type(): type 'fournisseur' is deprecated, please use 'supplier' instead", LOG_WARNING);
864 }
865
866 $this->db->begin();
867
868 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type]);
869 $sql .= " WHERE fk_categorie = ".((int) $this->id);
870 $sql .= " AND fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = ".((int) $obj->id);
871
872 dol_syslog(get_class($this).'::del_type', LOG_DEBUG);
873 if ($this->db->query($sql)) {
874 // Call trigger
875 $this->context = array('unlinkoff' => $obj); // Save object we want to link category to into category instance to provide information to trigger
876 $result = $this->call_trigger('CATEGORY_UNLINK', $user);
877 if ($result < 0) {
878 $error++;
879 }
880 // End call triggers
881
882 if (!$error) {
883 $this->db->commit();
884 return 1;
885 } else {
886 $this->db->rollback();
887 return -2;
888 }
889 } else {
890 $this->db->rollback();
891 $this->error = $this->db->lasterror();
892 return -1;
893 }
894 }
895
911 public function getObjectsInCateg($type, $onlyids = 0, $limit = 0, $offset = 0, $sortfield = '', $sortorder = 'ASC', $filter = '', $filtermode = 'AND')
912 {
913 global $user;
914
915 $objs = array();
916
917 $classnameforobj = $this->MAP_OBJ_CLASS[$type];
918 $obj = new $classnameforobj($this->db);
919
920 $sql = "SELECT c.fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." as fk_object";
921 $sql .= " FROM ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type])." as c";
922 $sql .= ", ".MAIN_DB_PREFIX.(empty($this->MAP_OBJ_TABLE[$type]) ? $type : $this->MAP_OBJ_TABLE[$type])." as o";
923 $sql .= " WHERE o.entity IN (".getEntity($obj->element).")";
924 $sql .= " AND c.fk_categorie = ".((int) $this->id);
925 // Compatibility with actioncomm table which has id instead of rowid
926 if ((array_key_exists($type, $this->MAP_OBJ_TABLE) && $this->MAP_OBJ_TABLE[$type] == "actioncomm") || $type == "actioncomm") {
927 $sql .= " AND c.fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = o.id";
928 } else {
929 $sql .= " AND c.fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = o.rowid";
930 }
931 // Protection for external users
932 if (($type == 'customer' || $type == 'supplier') && $user->socid > 0) {
933 $sql .= " AND o.rowid = ".((int) $user->socid);
934 }
935
936 $errormessage = '';
937 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
938 if ($errormessage) {
939 $this->errors[] = $errormessage;
940 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
941 return -1;
942 }
943
944 $sql .= $this->db->order($sortfield, $sortorder);
945 if ($limit > 0 || $offset > 0) {
946 $sql .= $this->db->plimit($limit + 1, $offset);
947 }
948
949 dol_syslog(get_class($this)."::getObjectsInCateg", LOG_DEBUG);
950
951 $resql = $this->db->query($sql);
952 if ($resql) {
953 while ($rec = $this->db->fetch_array($resql)) {
954 if ($onlyids) {
955 $objs[] = $rec['fk_object'];
956 } else {
957 $classnameforobj = $this->MAP_OBJ_CLASS[$type];
958
959 $obj = new $classnameforobj($this->db);
960 $obj->fetch($rec['fk_object']);
961 if ($obj->id > 0) { // Failing fetch may happen for example when a category supplier was set and third party was moved as customer only. The object supplier can't be loaded.
962 $objs[] = $obj;
963 }
964 }
965 }
966 return $objs;
967 } else {
968 $this->error = $this->db->error().' sql='.$sql;
969 return -1;
970 }
971 }
972
981 public function containsObject($type, $object_id)
982 {
983 $sql = "SELECT COUNT(*) as nb FROM ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type]);
984 $sql .= " WHERE fk_categorie = ".((int) $this->id)." AND fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = ".((int) $object_id);
985
986 dol_syslog(get_class($this)."::containsObject", LOG_DEBUG);
987
988 $resql = $this->db->query($sql);
989 if ($resql) {
990 return $this->db->fetch_object($resql)->nb;
991 } else {
992 $this->error = $this->db->error();
993 return -1;
994 }
995 }
996
1008 public function getListForItem($id, $type = 'customer', $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
1009 {
1010 $categories = array();
1011
1012 $type = sanitizeVal($type, 'aZ09');
1013
1014 $sub_type = $type;
1015 $subcol_name = "fk_".$type;
1016 if ($type == "customer") {
1017 $sub_type = "societe";
1018 $subcol_name = "fk_soc";
1019 }
1020 if ($type == "supplier") {
1021 $sub_type = "fournisseur";
1022 $subcol_name = "fk_soc";
1023 }
1024 if ($type == "contact") {
1025 $subcol_name = "fk_socpeople";
1026 }
1027
1028 $idoftype = array_search($type, self::$MAP_ID_TO_CODE);
1029
1030 $sql = "SELECT s.rowid";
1031 $sql .= " FROM ".MAIN_DB_PREFIX."categorie as s, ".MAIN_DB_PREFIX."categorie_".$sub_type." as sub";
1032 $sql .= ' WHERE s.entity IN ('.getEntity('category').')';
1033 $sql .= ' AND s.type='.((int) $idoftype);
1034 $sql .= ' AND s.rowid = sub.fk_categorie';
1035 $sql .= " AND sub.".$subcol_name." = ".((int) $id);
1036
1037 $sql .= $this->db->order($sortfield, $sortorder);
1038
1039 $offset = 0;
1040 $nbtotalofrecords = '';
1041 if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
1042 $result = $this->db->query($sql);
1043 $nbtotalofrecords = $this->db->num_rows($result);
1044 if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
1045 $page = 0;
1046 $offset = 0;
1047 }
1048 }
1049
1050 if ($limit) {
1051 if ($page < 0) {
1052 $page = 0;
1053 }
1054 $offset = $limit * $page;
1055
1056 $sql .= $this->db->plimit($limit + 1, $offset);
1057 }
1058
1059 $result = $this->db->query($sql);
1060 if ($result) {
1061 $i = 0;
1062 $num = $this->db->num_rows($result);
1063 $min = min($num, ($limit <= 0 ? $num : $limit));
1064 while ($i < $min) {
1065 $obj = $this->db->fetch_object($result);
1066 $category_static = new Categorie($this->db);
1067 if ($category_static->fetch($obj->rowid)) {
1068 $categories[$i]['id'] = $category_static->id;
1069 $categories[$i]['fk_parent'] = $category_static->fk_parent;
1070 $categories[$i]['label'] = $category_static->label;
1071 $categories[$i]['description'] = $category_static->description;
1072 $categories[$i]['color'] = $category_static->color;
1073 $categories[$i]['position'] = $category_static->position;
1074 $categories[$i]['socid'] = $category_static->socid;
1075 $categories[$i]['ref_ext'] = $category_static->ref_ext;
1076 $categories[$i]['visible'] = $category_static->visible;
1077 $categories[$i]['type'] = $category_static->type;
1078 $categories[$i]['entity'] = $category_static->entity;
1079 $categories[$i]['array_options'] = $category_static->array_options;
1080
1081 // multilangs
1082 if (getDolGlobalInt('MAIN_MULTILANGS') && isset($category_static->multilangs)) {
1083 $categories[$i]['multilangs'] = $category_static->multilangs;
1084 }
1085 }
1086 $i++;
1087 }
1088 } else {
1089 $this->error = $this->db->lasterror();
1090 return -1;
1091 }
1092 if (!count($categories)) {
1093 return 0;
1094 }
1095
1096 return $categories;
1097 }
1098
1099 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1105 public function get_filles()
1106 {
1107 // phpcs:enable
1108 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
1109 $sql .= " WHERE fk_parent = ".((int) $this->id);
1110 $sql .= " AND entity IN (".getEntity('category').")";
1111
1112 $res = $this->db->query($sql);
1113 if ($res) {
1114 $cats = array();
1115 while ($rec = $this->db->fetch_array($res)) {
1116 $cat = new Categorie($this->db);
1117 $cat->fetch($rec['rowid']);
1118 $cats[] = $cat;
1119 }
1120 return $cats;
1121 } else {
1122 dol_print_error($this->db);
1123 return -1;
1124 }
1125 }
1126
1127 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1133 protected function load_motherof()
1134 {
1135 // phpcs:enable
1136 $this->motherof = array();
1137
1138 // Load array[child]=parent
1139 $sql = "SELECT fk_parent as id_parent, rowid as id_son";
1140 $sql .= " FROM ".MAIN_DB_PREFIX."categorie";
1141 $sql .= " WHERE fk_parent != 0";
1142 $sql .= " AND entity IN (".getEntity('category').")";
1143
1144 dol_syslog(get_class($this)."::load_motherof", LOG_DEBUG);
1145 $resql = $this->db->query($sql);
1146 if ($resql) {
1147 while ($obj = $this->db->fetch_object($resql)) {
1148 $this->motherof[$obj->id_son] = $obj->id_parent;
1149 }
1150 return 1;
1151 } else {
1152 dol_print_error($this->db);
1153 return -1;
1154 }
1155 }
1156
1157 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1177 public function get_full_arbo($type, $fromid = 0, $include = 0)
1178 {
1179 // phpcs:enable
1180 global $langs;
1181
1182 if (!is_numeric($type)) {
1183 $type = $this->MAP_ID[$type];
1184 }
1185 if (is_null($type)) {
1186 $this->error = 'BadValueForParameterType';
1187 return -1;
1188 }
1189
1190 if (is_string($fromid)) {
1191 $fromid = explode(',', $fromid);
1192 } elseif (is_numeric($fromid)) {
1193 if ($fromid > 0) {
1194 $fromid = array($fromid);
1195 } else {
1196 $fromid = array();
1197 }
1198 } elseif (!is_array($fromid)) {
1199 $fromid = array();
1200 }
1201
1202 $this->cats = array();
1203 $nbcateg = 0;
1204
1205 // Init this->motherof that is array(id_son=>id_parent, ...)
1206 $this->load_motherof();
1207 $current_lang = $langs->getDefaultLang();
1208
1209 // Init $this->cats array
1210 $sql = "SELECT DISTINCT c.rowid, c.label, c.ref_ext, c.description, c.color, c.position, c.fk_parent, c.visible"; // Distinct reduce pb with old tables with duplicates
1211 if (getDolGlobalInt('MAIN_MULTILANGS')) {
1212 $sql .= ", t.label as label_trans, t.description as description_trans";
1213 }
1214 $sql .= " FROM ".MAIN_DB_PREFIX."categorie as c";
1215 if (getDolGlobalInt('MAIN_MULTILANGS')) {
1216 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_lang as t ON t.fk_category=c.rowid AND t.lang='".$this->db->escape($current_lang)."'";
1217 }
1218 $sql .= " WHERE c.entity IN (".getEntity('category').")";
1219 $sql .= " AND c.type = ".(int) $type;
1220
1221 dol_syslog(get_class($this)."::get_full_arbo get category list", LOG_DEBUG);
1222 $resql = $this->db->query($sql);
1223 if ($resql) {
1224 $i = 0;
1225 $nbcateg = $this->db->num_rows($resql);
1226
1227 while ($obj = $this->db->fetch_object($resql)) {
1228 $this->cats[$obj->rowid]['rowid'] = $obj->rowid;
1229 $this->cats[$obj->rowid]['id'] = $obj->rowid;
1230 $this->cats[$obj->rowid]['fk_parent'] = $obj->fk_parent;
1231 $this->cats[$obj->rowid]['label'] = !empty($obj->label_trans) ? $obj->label_trans : $obj->label;
1232 $this->cats[$obj->rowid]['description'] = !empty($obj->description_trans) ? $obj->description_trans : $obj->description;
1233 $this->cats[$obj->rowid]['color'] = $obj->color;
1234 $this->cats[$obj->rowid]['position'] = $obj->position;
1235 $this->cats[$obj->rowid]['visible'] = $obj->visible;
1236 $this->cats[$obj->rowid]['ref_ext'] = $obj->ref_ext;
1237 $this->cats[$obj->rowid]['picto'] = 'category';
1238 // fields are filled with buildPathFromId
1239 $this->cats[$obj->rowid]['fullpath'] = '';
1240 $this->cats[$obj->rowid]['fulllabel'] = '';
1241 $i++;
1242 }
1243 } else {
1244 dol_print_error($this->db);
1245 return -1;
1246 }
1247
1248 // We add the fullpath property to each elements of first level (no parent exists)
1249 dol_syslog(get_class($this)."::get_full_arbo call to buildPathFromId", LOG_DEBUG);
1250 foreach ($this->cats as $key => $val) {
1251 //print 'key='.$key.'<br>'."\n";
1252 $this->buildPathFromId($key, $nbcateg); // Process a branch from the root category key (this category has no parent)
1253 }
1254
1255 // Include or exclude leaf (including $fromid) from tree
1256 if (count($fromid) > 0) {
1257 $keyfiltercatid = '('.implode('|', $fromid).')';
1258
1259 //print "Look to discard category ".$fromid."\n";
1260 $keyfilter1 = '^'.$keyfiltercatid.'$';
1261 $keyfilter2 = '_'.$keyfiltercatid.'$';
1262 $keyfilter3 = '^'.$keyfiltercatid.'_';
1263 $keyfilter4 = '_'.$keyfiltercatid.'_';
1264 foreach (array_keys($this->cats) as $key) {
1265 $fullpath = (string) $this->cats[$key]['fullpath'];
1266 $test = (preg_match('/'.$keyfilter1.'/', $fullpath) || preg_match('/'.$keyfilter2.'/', $fullpath)
1267 || preg_match('/'.$keyfilter3.'/', $fullpath) || preg_match('/'.$keyfilter4.'/', $fullpath));
1268
1269 if (($test && !$include) || (!$test && $include)) {
1270 unset($this->cats[$key]);
1271 }
1272 }
1273 }
1274
1275 dol_syslog(get_class($this)."::get_full_arbo dol_sort_array", LOG_DEBUG);
1276
1277 $this->cats = dol_sort_array($this->cats, 'fulllabel', 'asc', 1, 0, 1); // Sort on full label like "Label 1 >> Sublabel a >> Subsublabel"
1278
1279 return $this->cats;
1280 }
1281
1292 private function buildPathFromId($id_categ, $protection = 1000)
1293 {
1294 //dol_syslog(get_class($this)."::buildPathFromId id_categ=".$id_categ." protection=".$protection, LOG_DEBUG);
1295
1296 if (!empty($this->cats[$id_categ]['fullpath'])) {
1297 // Already defined
1298 dol_syslog(get_class($this)."::buildPathFromId fullpath and fulllabel already defined", LOG_WARNING);
1299 return -1;
1300 }
1301
1302 // First build full array $motherof
1303 //$this->load_motherof(); // Disabled because already done by caller of buildPathFromId
1304
1305 // $this->cats[$id_categ] is supposed to be already an array. We just want to complete it with property fullpath and fulllabel
1306
1307 // Define fullpath and fulllabel
1308 $this->cats[$id_categ]['fullpath'] = '_'.$id_categ;
1309 $this->cats[$id_categ]['fulllabel'] = $this->cats[$id_categ]['label'];
1310 $i = 0;
1311 $cursor_categ = $id_categ;
1312 //print 'Work for id_categ='.$id_categ.'<br>'."\n";
1313 while ((empty($protection) || $i < $protection) && !empty($this->motherof[$cursor_categ])) {
1314 //print '&nbsp; cursor_categ='.$cursor_categ.' i='.$i.' '.$this->motherof[$cursor_categ].'<br>'."\n";
1315 $this->cats[$id_categ]['fullpath'] = '_'.$this->motherof[$cursor_categ].$this->cats[$id_categ]['fullpath'];
1316 $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'];
1317 //print '&nbsp; Result for id_categ='.$id_categ.' : '.$this->cats[$id_categ]['fullpath'].' '.$this->cats[$id_categ]['fulllabel'].'<br>'."\n";
1318 $i++;
1319 $cursor_categ = $this->motherof[$cursor_categ];
1320 }
1321 //print 'Result for id_categ='.$id_categ.' : '.$this->cats[$id_categ]['fullpath'].'<br>'."\n";
1322
1323 // We count number of _ to have level
1324 $nbunderscore = substr_count($this->cats[$id_categ]['fullpath'], '_');
1325 $this->cats[$id_categ]['level'] = ($nbunderscore ? $nbunderscore : null);
1326
1327 return 1;
1328 }
1329
1330
1331 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1339 public function get_all_categories($type = null, $parent = false)
1340 {
1341 // phpcs:enable
1342 if (!is_numeric($type)) {
1343 $type = $this->MAP_ID[$type];
1344 }
1345
1346 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
1347 $sql .= " WHERE entity IN (".getEntity('category').")";
1348 if (!is_null($type)) {
1349 $sql .= " AND type = ".(int) $type;
1350 }
1351 if ($parent) {
1352 $sql .= " AND fk_parent = 0";
1353 }
1354
1355 $res = $this->db->query($sql);
1356 if ($res) {
1357 $cats = array();
1358 while ($rec = $this->db->fetch_array($res)) {
1359 $cat = new Categorie($this->db);
1360 $cat->fetch($rec['rowid']);
1361 $cats[$rec['rowid']] = $cat;
1362 }
1363 return $cats;
1364 } else {
1365 dol_print_error($this->db);
1366 return -1;
1367 }
1368 }
1369
1370 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1377 public function get_main_categories($type = null)
1378 {
1379 // phpcs:enable
1380 return $this->get_all_categories($type, true);
1381 }
1382
1383 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1389 public function already_exists()
1390 {
1391 // phpcs:enable
1392 $type = $this->type;
1393
1394 if (!is_numeric($type)) {
1395 $type = $this->MAP_ID[$type];
1396 }
1397
1398 /* We have to select any rowid from llx_categorie which category's mother and label
1399 * are equals to those of the calling category
1400 */
1401 $sql = "SELECT c.rowid";
1402 $sql .= " FROM ".MAIN_DB_PREFIX."categorie as c ";
1403 $sql .= " WHERE c.entity IN (".getEntity('category').")";
1404 $sql .= " AND c.type = ".((int) $type);
1405 $sql .= " AND c.fk_parent = ".((int) $this->fk_parent);
1406 $sql .= " AND c.label = '".$this->db->escape($this->label)."'";
1407
1408 dol_syslog(get_class($this)."::already_exists", LOG_DEBUG);
1409
1410 $resql = $this->db->query($sql);
1411 if ($resql) {
1412 if ($this->db->num_rows($resql) > 0) { // Checking for empty resql
1413 $obj = $this->db->fetch_object($resql);
1414 /* If object called create, obj cannot have is id.
1415 * If object called update, he mustn't have the same label as an other category for this mother.
1416 * So if the result has the same id, update is not for label, and if result has an other one, update may be for label.
1417 */
1418 if (!empty($obj) && $obj->rowid > 0 && $obj->rowid != $this->id) {
1419 dol_syslog(get_class($this)."::already_exists category with name=".$this->label." and parent ".$this->fk_parent." exists: rowid=".$obj->rowid." current_id=".$this->id, LOG_DEBUG);
1420 return 1;
1421 }
1422 }
1423 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);
1424 return 0;
1425 } else {
1426 $this->error = $this->db->error();
1427 return -1;
1428 }
1429 }
1430
1431
1432 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1443 public function print_all_ways($sep = '&gt;&gt;', $url = '', $nocolor = 0, $addpicto = 0)
1444 {
1445 // phpcs:enable
1446 $ways = array();
1447
1448 $all_ways = $this->get_all_ways(); // Load array of categories
1449 foreach ($all_ways as $way) {
1450 $w = array();
1451 $i = 0;
1452 $forced_color = '';
1453 foreach ($way as $cat) {
1454 $i++;
1455
1456 if (empty($nocolor)) {
1457 $forced_color = 'colortoreplace';
1458 if ($i == count($way)) { // Last category in hierarchy
1459 // Check contrast with background and correct text color
1460 $forced_color = 'categtextwhite';
1461 if ($cat->color) {
1462 if (colorIsLight($cat->color)) {
1463 $forced_color = 'categtextblack';
1464 }
1465 }
1466 }
1467 }
1468
1469 if ($url == '') {
1470 $link = '<a href="'.DOL_URL_ROOT.'/categories/viewcat.php?id='.$cat->id.'&type='.$cat->type.'" class="'.$forced_color.'">';
1471 $linkend = '</a>';
1472 $w[] = $link.(($addpicto && $i == 1) ? img_object('', 'category', 'class="paddingright"') : '').$cat->label.$linkend;
1473 } elseif ($url == 'none') {
1474 $link = '<span class="'.$forced_color.'">';
1475 $linkend = '</span>';
1476 $w[] = $link.(($addpicto && $i == 1) ? img_object('', 'category', 'class="paddingright"') : '').$cat->label.$linkend;
1477 } else {
1478 $w[] = '<a class="'.$forced_color.'" href="'.DOL_URL_ROOT.'/'.$url.'?catid='.$cat->id.'">'.($addpicto ? img_object('', 'category') : '').$cat->label.'</a>';
1479 }
1480 }
1481 $newcategwithpath = preg_replace('/colortoreplace/', $forced_color, implode('<span class="inline-block valignmiddle paddingleft paddingright '.$forced_color.'">'.$sep.'</span>', $w));
1482
1483 $ways[] = $newcategwithpath;
1484 }
1485
1486 return $ways;
1487 }
1488
1489
1490 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1496 public function get_meres()
1497 {
1498 // phpcs:enable
1499 $parents = array();
1500
1501 $sql = "SELECT fk_parent FROM ".MAIN_DB_PREFIX."categorie";
1502 $sql .= " WHERE rowid = ".((int) $this->id);
1503
1504 $res = $this->db->query($sql);
1505
1506 if ($res) {
1507 while ($rec = $this->db->fetch_array($res)) {
1508 if ($rec['fk_parent'] > 0) {
1509 $cat = new Categorie($this->db);
1510 $cat->fetch($rec['fk_parent']);
1511 $parents[] = $cat;
1512 }
1513 }
1514 return $parents;
1515 } else {
1516 dol_print_error($this->db);
1517 return -1;
1518 }
1519 }
1520
1521 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1528 public function get_all_ways()
1529 {
1530 // phpcs:enable
1531 $ways = array();
1532
1533 $parents = $this->get_meres();
1534 if (is_array($parents)) {
1535 foreach ($parents as $parent) {
1536 $all_ways = $parent->get_all_ways();
1537 foreach ($all_ways as $way) {
1538 $w = $way;
1539 $w[] = $this;
1540 $ways[] = $w;
1541 }
1542 }
1543 }
1544
1545 if (count($ways) == 0) {
1546 $ways[0][0] = $this;
1547 }
1548
1549 return $ways;
1550 }
1551
1562 public function containing($id, $type, $mode = 'object')
1563 {
1564 $cats = array();
1565
1566 if (is_numeric($type)) {
1567 $type = Categorie::$MAP_ID_TO_CODE[$type];
1568 }
1569
1570 if ($type === Categorie::TYPE_BANK_LINE) { // TODO Remove this with standard category code after migration of llx_bank_categ into llx_categorie
1571 // Load bank categories
1572 $sql = "SELECT c.label, c.rowid";
1573 $sql .= " FROM ".MAIN_DB_PREFIX."bank_class as a, ".MAIN_DB_PREFIX."bank_categ as c";
1574 $sql .= " WHERE a.lineid=".((int) $id)." AND a.fk_categ = c.rowid";
1575 $sql .= " AND c.entity IN (".getEntity('category').")";
1576 $sql .= " ORDER BY c.label";
1577
1578 $res = $this->db->query($sql);
1579 if ($res) {
1580 while ($obj = $this->db->fetch_object($res)) {
1581 if ($mode == 'id') {
1582 $cats[] = $obj->rowid;
1583 } elseif ($mode == 'label') {
1584 $cats[] = $obj->label;
1585 } else {
1586 $cat = new Categorie($this->db);
1587 $cat->id = $obj->rowid;
1588 $cat->label = $obj->label;
1589 $cats[] = $cat;
1590 }
1591 }
1592 } else {
1593 dol_print_error($this->db);
1594 return -1;
1595 }
1596 } else {
1597 $sql = "SELECT ct.fk_categorie, c.label, c.rowid";
1598 $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";
1599 $sql .= " WHERE ct.fk_categorie = c.rowid AND ct.fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = ".(int) $id;
1600 // This seems useless because the table already contains id of category of 1 unique type. So commented.
1601 // So now it works also with external added categories.
1602 //$sql .= " AND c.type = ".((int) $this->MAP_ID[$type]);
1603 $sql .= " AND c.entity IN (".getEntity('category').")";
1604
1605 $res = $this->db->query($sql);
1606 if ($res) {
1607 while ($obj = $this->db->fetch_object($res)) {
1608 if ($mode == 'id') {
1609 $cats[] = $obj->rowid;
1610 } elseif ($mode == 'label') {
1611 $cats[] = $obj->label;
1612 } else {
1613 $cat = new Categorie($this->db);
1614 $cat->fetch($obj->fk_categorie);
1615 $cats[] = $cat;
1616 }
1617 }
1618 } else {
1619 dol_print_error($this->db);
1620 return -1;
1621 }
1622 }
1623
1624 return $cats;
1625 }
1626
1638 public function rechercher($id, $nom, $type, $exact = false, $case = false)
1639 {
1640 // Deprecation warning
1641 if (is_numeric($type)) {
1642 dol_syslog(__METHOD__.': using numeric types is deprecated.', LOG_WARNING);
1643 }
1644
1645 $cats = array();
1646
1647 // For backward compatibility
1648 if (is_numeric($type)) {
1649 // We want to reverse lookup
1650 $map_type = array_flip($this->MAP_ID);
1651 $type = $map_type[$type];
1652 dol_syslog(get_class($this)."::rechercher(): numeric types are deprecated, please use string instead", LOG_WARNING);
1653 }
1654
1655 // Generation requete recherche
1656 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
1657 $sql .= " WHERE type = ".((int) $this->MAP_ID[$type]);
1658 $sql .= " AND entity IN (".getEntity('category').")";
1659 if ($nom) {
1660 if (!$exact) {
1661 $nom = '%'.$this->db->escape(str_replace('*', '%', $nom)).'%';
1662 }
1663 if (!$case) {
1664 $sql .= " AND label LIKE '".$this->db->escape($nom)."'";
1665 } else {
1666 $sql .= " AND label LIKE BINARY '".$this->db->escape($nom)."'";
1667 }
1668 }
1669 if ($id) {
1670 $sql .= " AND rowid = ".((int) $id);
1671 }
1672
1673 $res = $this->db->query($sql);
1674 if ($res) {
1675 while ($rec = $this->db->fetch_array($res)) {
1676 $cat = new Categorie($this->db);
1677 $cat->fetch($rec['rowid']);
1678 $cats[] = $cat;
1679 }
1680
1681 return $cats;
1682 } else {
1683 $this->error = $this->db->error().' sql='.$sql;
1684 return -1;
1685 }
1686 }
1687
1694 public function isAnyPhotoAvailable($sdir)
1695 {
1696 include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
1697 include_once DOL_DOCUMENT_ROOT . '/core/lib/images.lib.php';
1698
1699 $sdir .= '/' . get_exdir($this->id, 2, 0, 0, $this, 'category') . $this->id . "/photos/";
1700
1701 $dir_osencoded = dol_osencode($sdir);
1702 if (file_exists($dir_osencoded)) {
1703 $handle = opendir($dir_osencoded);
1704 if (is_resource($handle)) {
1705 while (($file = readdir($handle)) !== false) {
1706 if (!utf8_check($file)) {
1707 $file = mb_convert_encoding($file, 'UTF-8', 'ISO-8859-1'); // To be sure data is stored in UTF8 in memory
1708 }
1709 if (dol_is_file($sdir . $file) && image_format_supported($file) >= 0) {
1710 return true;
1711 }
1712 }
1713 }
1714 }
1715 return false;
1716 }
1717
1724 public function getTooltipContentArray($params)
1725 {
1726 global $langs;
1727
1728 $langs->load('categories');
1729
1730 $datas = [];
1731
1732 $datas['label'] = $langs->trans("ShowCategory").': '.($this->ref ? $this->ref : $this->label);
1733
1734 return $datas;
1735 }
1736
1750 public function getNomUrl($withpicto = 0, $option = '', $maxlength = 0, $moreparam = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = 0)
1751 {
1752 global $conf, $langs, $hookmanager;
1753
1754 if (!empty($conf->dol_no_mouse_hover)) {
1755 $notooltip = 1; // Force disable tooltips
1756 }
1757
1758 $result = '';
1759 $params = [
1760 'id' => $this->id,
1761 'objecttype' => $this->element,
1762 'option' => $option,
1763 ];
1764 $classfortooltip = 'classfortooltip';
1765 $dataparams = '';
1766 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1767 $classfortooltip = 'classforajaxtooltip';
1768 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1769 $label = '';
1770 } else {
1771 $label = implode($this->getTooltipContentArray($params));
1772 }
1773
1774 $url = DOL_URL_ROOT.'/categories/viewcat.php?id='.$this->id.'&type='.$this->type.$moreparam.'&backtopage='.urlencode($_SERVER['PHP_SELF'].($moreparam ? '?'.$moreparam : ''));
1775
1776 if ($option !== 'nolink') {
1777 // Add param to save lastsearch_values or not
1778 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1779 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1780 $add_save_lastsearch_values = 1;
1781 }
1782 if ($url && $add_save_lastsearch_values) {
1783 $url .= '&save_lastsearch_values=1';
1784 }
1785 }
1786
1787 // Check contrast with background and correct text color
1788 $forced_color = 'categtextwhite'; // We want color white because the background is dark (grey or other)
1789 if ($this->color) {
1790 if (colorIsLight($this->color)) { // If color is light, we force color to dark
1791 $forced_color = 'categtextblack';
1792 }
1793 }
1794
1795 $linkclose = '';
1796 if (empty($notooltip)) {
1797 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1798 $label = $langs->trans("ShowMyObject");
1799 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1800 }
1801 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1802 $linkclose .= $dataparams.' class="'.$classfortooltip.' '.$forced_color.($morecss ? ' '.$morecss : '').'"';
1803 } else {
1804 $linkclose = ($morecss ? ' class="'.$forced_color.($morecss ? ' '.$morecss : '').'"' : '');
1805 }
1806
1807 if ($option == 'nolink' || empty($url)) {
1808 $linkstart = '<span';
1809 } else {
1810 $linkstart = '<a href="'.$url.'"';
1811 }
1812 $linkstart .= $linkclose.'>';
1813 if ($option == 'nolink' || empty($url)) {
1814 $linkend = '</span>';
1815 } else {
1816 $linkend = '</a>';
1817 }
1818
1819 $result .= $linkstart;
1820
1821 if ($withpicto) {
1822 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1823 }
1824
1825 if ($withpicto != 2) {
1826 $result .= dol_trunc(($this->ref ? $this->ref : $this->label), $maxlength);
1827 }
1828
1829 $result .= $linkend;
1830
1831 global $action;
1832 $hookmanager->initHooks(array($this->element . 'dao'));
1833 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1834 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1835 if ($reshook > 0) {
1836 $result = $hookmanager->resPrint;
1837 } else {
1838 $result .= $hookmanager->resPrint;
1839 }
1840 return $result;
1841 }
1842
1843
1844 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1852 public function add_photo($sdir, $file)
1853 {
1854 // phpcs:enable
1855 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1856
1857 $dir = $sdir.'/'.get_exdir($this->id, 2, 0, 0, $this, 'category').$this->id."/";
1858 $dir .= "photos/";
1859
1860 if (!file_exists($dir)) {
1861 dol_mkdir($dir);
1862 }
1863
1864 if (file_exists($dir)) {
1865 if (is_array($file['name']) && count($file['name']) > 0) {
1866 $nbfile = count($file['name']);
1867 for ($i = 0; $i < $nbfile; $i++) {
1868 $originImage = $dir.$file['name'][$i];
1869
1870 // Cree fichier en taille origine
1871 dol_move_uploaded_file($file['tmp_name'][$i], $originImage, 1, 0, 0);
1872
1873 if (file_exists($originImage)) {
1874 // Create thumbs
1875 $this->addThumbs($originImage);
1876 }
1877 }
1878 } else {
1879 $originImage = $dir.$file['name'];
1880
1881 // Cree fichier en taille origine
1882 dol_move_uploaded_file($file['tmp_name'], $originImage, 1, 0, 0);
1883
1884 if (file_exists($originImage)) {
1885 // Create thumbs
1886 $this->addThumbs($originImage);
1887 }
1888 }
1889 }
1890 }
1891
1892 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1900 public function liste_photos($dir, $nbmax = 0)
1901 {
1902 // phpcs:enable
1903 include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1904
1905 $nbphoto = 0;
1906 $tabobj = array();
1907
1908 $dirthumb = $dir.'thumbs/';
1909
1910 if (file_exists($dir)) {
1911 $handle = opendir($dir);
1912 if (is_resource($handle)) {
1913 while (($file = readdir($handle)) !== false) {
1914 if (dol_is_file($dir.$file) && preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i', $dir.$file)) {
1915 $nbphoto++;
1916 $photo = $file;
1917
1918 // On determine nom du fichier vignette
1919 $photo_vignette = '';
1920 $regs = array();
1921 if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i', $photo, $regs)) {
1922 $photo_vignette = preg_replace('/'.$regs[0].'/i', '', $photo).'_small'.$regs[0];
1923 }
1924
1925 // Object
1926 $obj = array();
1927 $obj['photo'] = $photo;
1928 if ($photo_vignette && is_file($dirthumb.$photo_vignette)) {
1929 $obj['photo_vignette'] = 'thumbs/'.$photo_vignette;
1930 } else {
1931 $obj['photo_vignette'] = "";
1932 }
1933
1934 $tabobj[$nbphoto - 1] = $obj;
1935
1936 // On continue ou on arrete de boucler
1937 if ($nbmax && $nbphoto >= $nbmax) {
1938 break;
1939 }
1940 }
1941 }
1942
1943 closedir($handle);
1944 }
1945 }
1946
1947 return $tabobj;
1948 }
1949
1950 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1957 public function delete_photo($file)
1958 {
1959 // phpcs:enable
1960 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1961
1962 $dir = dirname($file).'/'; // Chemin du dossier contenant l'image d'origine
1963 $dirthumb = $dir.'/thumbs/'; // Chemin du dossier contenant la vignette
1964 $filename = preg_replace('/'.preg_quote($dir, '/').'/i', '', $file); // Nom du fichier
1965
1966 // On efface l'image d'origine
1967 dol_delete_file($file, 1);
1968
1969 // Si elle existe, on efface la vignette
1970 $regs = array();
1971 if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i', $filename, $regs)) {
1972 $photo_vignette = preg_replace('/'.$regs[0].'/i', '', $filename).'_small'.$regs[0];
1973 if (file_exists($dirthumb.$photo_vignette)) {
1974 dol_delete_file($dirthumb.$photo_vignette, 1);
1975 }
1976 }
1977 }
1978
1979 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1986 public function get_image_size($file)
1987 {
1988 // phpcs:enable
1989 $infoImg = getimagesize($file); // Recuperation des infos de l'image
1990 $this->imgWidth = $infoImg[0]; // Largeur de l'image
1991 $this->imgHeight = $infoImg[1]; // Hauteur de l'image
1992 }
1993
2002 public function setMultiLangs(User $user, $notrigger = 0)
2003 {
2004 global $langs;
2005
2006 $langs_available = $langs->get_available_languages();
2007 $current_lang = $langs->getDefaultLang();
2008
2009 foreach ($langs_available as $key => $value) {
2010 $sql = "SELECT rowid";
2011 $sql .= " FROM ".MAIN_DB_PREFIX."categorie_lang";
2012 $sql .= " WHERE fk_category=".((int) $this->id);
2013 $sql .= " AND lang = '".$this->db->escape($key)."'";
2014
2015 $result = $this->db->query($sql);
2016
2017 if ($key == $current_lang) {
2018 $sql2 = '';
2019 if ($this->db->num_rows($result)) { // si aucune ligne dans la base
2020 $sql2 = "UPDATE ".MAIN_DB_PREFIX."categorie_lang";
2021 $sql2 .= " SET label = '".$this->db->escape($this->label)."',";
2022 $sql2 .= " description = '".$this->db->escape($this->description)."'";
2023 $sql2 .= " WHERE fk_category = ".((int) $this->id)." AND lang = '".$this->db->escape($key)."'";
2024 } elseif (isset($this->multilangs[$key])) {
2025 $sql2 = "INSERT INTO ".MAIN_DB_PREFIX."categorie_lang (fk_category, lang, label, description)";
2026 $sql2 .= " VALUES(".((int) $this->id).", '".$this->db->escape($key)."', '".$this->db->escape($this->label)."'";
2027 $sql2 .= ", '".$this->db->escape($this->multilangs[$key]["description"])."')";
2028 }
2029 dol_syslog(get_class($this).'::setMultiLangs', LOG_DEBUG);
2030 if ($sql2 && !$this->db->query($sql2)) {
2031 $this->error = $this->db->lasterror();
2032 return -1;
2033 }
2034 } elseif (isset($this->multilangs[$key])) {
2035 if ($this->db->num_rows($result)) { // si aucune ligne dans la base
2036 $sql2 = "UPDATE ".MAIN_DB_PREFIX."categorie_lang";
2037 $sql2 .= " SET label='".$this->db->escape($this->multilangs[$key]["label"])."',";
2038 $sql2 .= " description='".$this->db->escape($this->multilangs[$key]["description"])."'";
2039 $sql2 .= " WHERE fk_category=".((int) $this->id)." AND lang='".$this->db->escape($key)."'";
2040 } else {
2041 $sql2 = "INSERT INTO ".MAIN_DB_PREFIX."categorie_lang (fk_category, lang, label, description)";
2042 $sql2 .= " VALUES(".((int) $this->id).", '".$this->db->escape($key)."', '".$this->db->escape($this->multilangs[$key]["label"])."'";
2043 $sql2 .= ",'".$this->db->escape($this->multilangs[$key]["description"])."')";
2044 }
2045
2046 // on ne sauvegarde pas des champs vides
2047 if ($this->multilangs[$key]["label"] || $this->multilangs[$key]["description"] || $this->multilangs[$key]["note"]) {
2048 dol_syslog(get_class($this).'::setMultiLangs', LOG_DEBUG);
2049 }
2050 if (!$this->db->query($sql2)) {
2051 $this->error = $this->db->lasterror();
2052 return -1;
2053 }
2054 }
2055 }
2056
2057 // Call trigger
2058 if (!$notrigger) {
2059 $result = $this->call_trigger('CATEGORY_SET_MULTILANGS', $user);
2060 if ($result < 0) {
2061 $this->error = $this->db->lasterror();
2062 return -1;
2063 }
2064 }
2065 // End call triggers
2066
2067 return 1;
2068 }
2069
2075 public function getMultiLangs()
2076 {
2077 global $langs;
2078
2079 $current_lang = $langs->getDefaultLang();
2080
2081 $sql = "SELECT lang, label, description";
2082 $sql .= " FROM ".MAIN_DB_PREFIX."categorie_lang";
2083 $sql .= " WHERE fk_category=".((int) $this->id);
2084
2085 $result = $this->db->query($sql);
2086 if ($result) {
2087 while ($obj = $this->db->fetch_object($result)) {
2088 //print 'lang='.$obj->lang.' current='.$current_lang.'<br>';
2089 if ($obj->lang == $current_lang) { // si on a les traduct. dans la langue courante on les charge en infos principales.
2090 $this->label = $obj->label;
2091 $this->description = $obj->description;
2092 }
2093 $this->multilangs[$obj->lang]["label"] = $obj->label;
2094 $this->multilangs[$obj->lang]["description"] = $obj->description;
2095 }
2096 return 1;
2097 } else {
2098 $this->error = $langs->trans("Error")." : ".$this->db->error()." - ".$sql;
2099 return -1;
2100 }
2101 }
2102
2109 public function getLibStatut($mode)
2110 {
2111 return '';
2112 }
2113
2114
2122 public function initAsSpecimen()
2123 {
2124 dol_syslog(get_class($this)."::initAsSpecimen");
2125
2126 // Initialise parameters
2127 $this->id = 0;
2128 $this->fk_parent = 0;
2129 $this->label = 'SPECIMEN';
2130 $this->specimen = 1;
2131 $this->description = 'This is a description';
2132 $this->socid = 1;
2133 $this->type = self::TYPE_PRODUCT;
2134
2135 return 1;
2136 }
2137
2146 public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
2147 {
2148 $tables = array(
2149 'categorie_societe'
2150 );
2151
2152 return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables, 1);
2153 }
2154
2163 public static function getFilterJoinQuery($type, $rowIdName)
2164 {
2165 if ($type == 'bank_account') {
2166 $type = 'account';
2167 }
2168
2169 return " LEFT JOIN ".MAIN_DB_PREFIX."categorie_".$type." as cp ON ".$rowIdName." = cp.fk_".$type;
2170 }
2171
2181 public static function getFilterSelectQuery($type, $rowIdName, $searchList)
2182 {
2183 if ($type == 'bank_account') {
2184 $type = 'account';
2185 }
2186 if ($type == 'customer') {
2187 $type = 'societe';
2188 }
2189 if ($type == 'supplier') {
2190 $type = 'fournisseur';
2191 }
2192
2193 if (empty($searchList) && !is_array($searchList)) {
2194 return "";
2195 }
2196
2197 $searchCategorySqlList = array();
2198 foreach ($searchList as $searchCategory) {
2199 if (intval($searchCategory) == -2) {
2200 $searchCategorySqlList[] = " cp.fk_categorie IS NULL";
2201 } elseif (intval($searchCategory) > 0) {
2202 $searchCategorySqlList[] = " ".$rowIdName." IN (SELECT fk_".$type." FROM ".MAIN_DB_PREFIX."categorie_".$type." WHERE fk_categorie = ".((int) $searchCategory).")";
2203 }
2204 }
2205
2206 if (!empty($searchCategorySqlList)) {
2207 return " AND (".implode(' AND ', $searchCategorySqlList).")";
2208 } else {
2209 return "";
2210 }
2211 }
2212
2218 public function countNbOfCategories()
2219 {
2220 dol_syslog(get_class($this)."::count_all_categories", LOG_DEBUG);
2221 $sql = "SELECT COUNT(rowid) FROM ".MAIN_DB_PREFIX."categorie";
2222 $sql .= " WHERE entity IN (".getEntity('category').")";
2223
2224 $res = $this->db->query($sql);
2225 if ($res) {
2226 $obj = $this->db->fetch_object($res);
2227 return $obj->count;
2228 } else {
2229 dol_print_error($this->db);
2230 return -1;
2231 }
2232 }
2233}
print $object position
Definition edit.php:195
$object ref
Definition info.php:79
Class to manage categories.
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.
load_motherof()
Load the array this->motherof that is array(id_son=>id_parent, ...)
get_full_arbo($type, $fromid=0, $include=0)
Rebuilding the category tree as an array Return an array of table('id','id_mere',....
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 children available in this->cats, define property fullpath and fulllabe...
static getFilterSelectQuery($type, $rowIdName, $searchList)
Return the additional SQL SELECT query for filtering a list by a category.
create($user, $notrigger=0)
Add category into database.
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.
isAnyPhotoAvailable($sdir)
Return if at least one photo is available.
already_exists()
Check if a category with same label already exists for this cat's parent or root and for this cat's t...
get_filles()
Return direct children ids 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 additional 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.
setMultiLangs(User $user, $notrigger=0)
Update ou cree les traductions des infos produits.
getObjectsInCateg($type, $onlyids=0, $limit=0, $offset=0, $sortfield='', $sortorder='ASC', $filter='', $filtermode='AND')
Return list of fetched instance of elements having this category.
getMapList()
Get map list.
get_meres()
Returns an array containing the list of parent categories.
add_type($obj, $type='')
Link an object to the category.
update(User $user, $notrigger=0)
Update category.
liste_photos($dir, $nbmax=0)
Return an array with all photos inside the directory.
get_all_ways()
Returns in a table all possible paths to get to the category starting with the major categories repre...
getNomUrl($withpicto=0, $option='', $maxlength=0, $moreparam='', $notooltip=0, $morecss='', $save_lastsearch_value=0)
Return name and link of category (with picto) Use ->id, ->ref, ->label, ->color.
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...
add_photo($sdir, $file)
Add the image uploaded as $file to the directory $sdir/<category>-<id>/photos/.
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='')
Check validity of a file upload from an GUI page, and move it to its final destination.
dol_is_file($pathoffile)
Return if path is a file.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
colorIsLight($stringcolor)
Return true if the color is light.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
sanitizeVal($out='', $check='alphanohtml', $filter=null, $options=null)
Return a sanitized or empty value after checking value against a rule.
utf8_check($str)
Check if a string is in UTF8.
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)
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:137