dolibarr 19.0.3
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-2024 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
270 public $multilangs;
271
275 public $imgWidth;
276
280 public $imgHeight;
281
287 public function __construct($db)
288 {
289 global $hookmanager;
290
291 $this->db = $db;
292
293 if (is_object($hookmanager)) {
294 $hookmanager->initHooks(array('category'));
295 $parameters = array();
296 $reshook = $hookmanager->executeHooks('constructCategory', $parameters, $this); // Note that $action and $object may have been modified by some hooks
297 if ($reshook >= 0 && !empty($hookmanager->resArray)) {
298 foreach ($hookmanager->resArray as $mapList) {
299 $mapId = $mapList['id'];
300 $mapCode = $mapList['code'];
301 self::$MAP_ID_TO_CODE[$mapId] = $mapCode;
302 $this->MAP_ID[$mapCode] = $mapId;
303 $this->MAP_CAT_FK[$mapCode] = isset($mapList['cat_fk']) ? $mapList['cat_fk'] : null;
304 $this->MAP_CAT_TABLE[$mapCode] = isset($mapList['cat_table']) ? $mapList['cat_table'] : null;
305 $this->MAP_OBJ_CLASS[$mapCode] = $mapList['obj_class'];
306 $this->MAP_OBJ_TABLE[$mapCode] = $mapList['obj_table'];
307 }
308 }
309 }
310 }
311
317 public function getMapList()
318 {
319 $mapList = array();
320
321 foreach ($this->MAP_ID as $mapCode => $mapId) {
322 $mapList[] = array(
323 'id' => $mapId,
324 'code' => $mapCode,
325 'cat_fk' => (empty($this->MAP_CAT_FK[$mapCode]) ? $mapCode : $this->MAP_CAT_FK[$mapCode]),
326 'cat_table' => (empty($this->MAP_CAT_TABLE[$mapCode]) ? $mapCode : $this->MAP_CAT_TABLE[$mapCode]),
327 'obj_class' => (empty($this->MAP_OBJ_CLASS[$mapCode]) ? $mapCode : $this->MAP_OBJ_CLASS[$mapCode]),
328 'obj_table' => (empty($this->MAP_OBJ_TABLE[$mapCode]) ? $mapCode : $this->MAP_OBJ_TABLE[$mapCode])
329 );
330 }
331
332 return $mapList;
333 }
334
344 public function fetch($id, $label = '', $type = null, $ref_ext = '')
345 {
346 // Check parameters
347 if (empty($id) && empty($label) && empty($ref_ext)) {
348 $this->error = "No category to search for";
349 return -1;
350 }
351 if (!is_null($type) && !is_numeric($type)) {
352 $type = $this->MAP_ID[$type];
353 }
354
355 $sql = "SELECT rowid, fk_parent, entity, label, description, color, fk_soc, visible, type, ref_ext";
356 $sql .= ", date_creation, tms, fk_user_creat, fk_user_modif";
357 $sql .= " FROM ".MAIN_DB_PREFIX."categorie";
358 if ($id) {
359 $sql .= " WHERE rowid = ".((int) $id);
360 } elseif (!empty($ref_ext)) {
361 $sql .= " WHERE ref_ext LIKE '".$this->db->escape($ref_ext)."'";
362 } else {
363 $sql .= " WHERE label = '".$this->db->escape($label)."' AND entity IN (".getEntity('category').")";
364 if (!is_null($type)) {
365 $sql .= " AND type = ".((int) $type);
366 }
367 }
368
369 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
370 $resql = $this->db->query($sql);
371 if ($resql) {
372 if ($this->db->num_rows($resql) > 0) {
373 $res = $this->db->fetch_array($resql);
374
375 $this->id = $res['rowid'];
376 //$this->ref = $res['rowid'];
377 $this->fk_parent = (int) $res['fk_parent'];
378 $this->label = $res['label'];
379 $this->description = $res['description'];
380 $this->color = $res['color'];
381 $this->socid = (int) $res['fk_soc'];
382 $this->visible = (int) $res['visible'];
383 $this->type = (int) $res['type'];
384 $this->ref_ext = $res['ref_ext'];
385 $this->entity = (int) $res['entity'];
386 $this->date_creation = $this->db->jdate($res['date_creation']);
387 $this->date_modification = $this->db->jdate($res['tms']);
388 $this->user_creation_id = (int) $res['fk_user_creat'];
389 $this->user_modification_id = (int) $res['fk_user_modif'];
390
391 // Retrieve all extrafield
392 // fetch optionals attributes and labels
393 $this->fetch_optionals();
394
395 $this->db->free($resql);
396
397 // multilangs
398 if (getDolGlobalInt('MAIN_MULTILANGS')) {
399 $this->getMultiLangs();
400 }
401
402 return 1;
403 } else {
404 $this->error = "No category found";
405 return 0;
406 }
407 } else {
408 dol_print_error($this->db);
409 $this->error = $this->db->lasterror;
410 $this->errors[] = $this->db->lasterror;
411 return -1;
412 }
413 }
414
425 public function create($user, $notrigger = 0)
426 {
427 global $conf, $langs, $hookmanager;
428 $langs->load('categories');
429
430 $type = $this->type;
431
432 if (!is_numeric($type)) {
433 $type = $this->MAP_ID[$type];
434 }
435
436 $error = 0;
437
438 dol_syslog(get_class($this).'::create', LOG_DEBUG);
439
440 // Clean parameters
441 $this->label = trim($this->label);
442 $this->description = trim($this->description);
443 $this->color = trim($this->color);
444 $this->import_key = trim($this->import_key);
445 $this->ref_ext = trim($this->ref_ext);
446 if (empty($this->visible)) {
447 $this->visible = 0;
448 }
449 $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
450
451 if ($this->already_exists()) {
452 $this->error = $langs->trans("ImpossibleAddCat", $this->label);
453 $this->error .= " : ".$langs->trans("CategoryExistsAtSameLevel");
454 dol_syslog($this->error, LOG_WARNING);
455 return -4;
456 }
457
458 $this->db->begin();
459 $now = dol_now();
460 $sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie (";
461 $sql .= "fk_parent,";
462 $sql .= " label,";
463 $sql .= " description,";
464 $sql .= " color,";
465 if (getDolGlobalString('CATEGORY_ASSIGNED_TO_A_CUSTOMER')) {
466 $sql .= "fk_soc,";
467 }
468 $sql .= " visible,";
469 $sql .= " type,";
470 $sql .= " import_key,";
471 $sql .= " ref_ext,";
472 $sql .= " entity,";
473 $sql .= " date_creation,";
474 $sql .= " fk_user_creat";
475 $sql .= ") VALUES (";
476 $sql .= (int) $this->fk_parent.",";
477 $sql .= "'".$this->db->escape($this->label)."', ";
478 $sql .= "'".$this->db->escape($this->description)."', ";
479 $sql .= "'".$this->db->escape($this->color)."', ";
480 if (getDolGlobalString('CATEGORY_ASSIGNED_TO_A_CUSTOMER')) {
481 $sql .= ($this->socid > 0 ? $this->socid : 'null').", ";
482 }
483 $sql .= "'".$this->db->escape($this->visible)."', ";
484 $sql .= ((int) $type).", ";
485 $sql .= (!empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : 'null').", ";
486 $sql .= (!empty($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : 'null').", ";
487 $sql .= (int) $conf->entity.", ";
488 $sql .= "'".$this->db->idate($now)."', ";
489 $sql .= (int) $user->id;
490 $sql .= ")";
491
492 $res = $this->db->query($sql);
493 if ($res) {
494 $id = $this->db->last_insert_id(MAIN_DB_PREFIX."categorie");
495
496 if ($id > 0) {
497 $this->id = $id;
498
499 $action = 'create';
500
501 // Actions on extra fields
502 if (!$error) {
503 $result = $this->insertExtraFields();
504 if ($result < 0) {
505 $error++;
506 }
507 }
508
509 if (!$error && !$notrigger) {
510 // Call trigger
511 $result = $this->call_trigger('CATEGORY_CREATE', $user);
512 if ($result < 0) {
513 $error++;
514 }
515 // End call triggers
516 }
517
518 if (!$error) {
519 $this->db->commit();
520 return $id;
521 } else {
522 $this->db->rollback();
523 return -3;
524 }
525 } else {
526 $this->db->rollback();
527 return -2;
528 }
529 } else {
530 $this->error = $this->db->error();
531 $this->db->rollback();
532 return -1;
533 }
534 }
535
545 public function update(User $user, $notrigger = 0)
546 {
547 global $langs;
548
549 $error = 0;
550
551 // Clean parameters
552 $this->label = trim($this->label);
553 $this->description = trim($this->description);
554 $this->ref_ext = trim($this->ref_ext);
555 $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
556 $this->visible = ($this->visible != "" ? intval($this->visible) : 0);
557
558 if ($this->already_exists()) {
559 $this->error = $langs->trans("ImpossibleUpdateCat");
560 $this->error .= " : ".$langs->trans("CategoryExistsAtSameLevel");
561 return -1;
562 }
563
564 $this->db->begin();
565
566 $sql = "UPDATE ".MAIN_DB_PREFIX."categorie";
567 $sql .= " SET label = '".$this->db->escape($this->label)."',";
568 $sql .= " description = '".$this->db->escape($this->description)."',";
569 $sql .= " ref_ext = '".$this->db->escape($this->ref_ext)."',";
570 $sql .= " color = '".$this->db->escape($this->color)."'";
571 if (getDolGlobalString('CATEGORY_ASSIGNED_TO_A_CUSTOMER')) {
572 $sql .= ", fk_soc = ".($this->socid > 0 ? $this->socid : 'null');
573 }
574 $sql .= ", visible = ".(int) $this->visible;
575 $sql .= ", fk_parent = ".(int) $this->fk_parent;
576 $sql .= ", fk_user_modif = ".(int) $user->id;
577 $sql .= " WHERE rowid = ".((int) $this->id);
578
579 dol_syslog(get_class($this)."::update", LOG_DEBUG);
580 if ($this->db->query($sql)) {
581 $action = 'update';
582
583 // Actions on extra fields
584 if (!$error) {
585 $result = $this->insertExtraFields();
586 if ($result < 0) {
587 $error++;
588 }
589 }
590
591 if (!$error && !$notrigger) {
592 // Call trigger
593 $result = $this->call_trigger('CATEGORY_MODIFY', $user);
594 if ($result < 0) {
595 $error++;
596 }
597 // End call triggers
598 }
599
600 if (!$error) {
601 $this->db->commit();
602 return 1;
603 } else {
604 $this->db->rollback();
605 return -1;
606 }
607 } else {
608 $this->db->rollback();
609 dol_print_error($this->db);
610 return -1;
611 }
612 }
613
621 public function delete($user, $notrigger = 0)
622 {
623 $error = 0;
624
625 // Clean parameters
626 $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
627
628 dol_syslog(get_class($this)."::remove");
629
630 $this->db->begin();
631
632 if (!$error && !$notrigger) {
633 // Call trigger
634 $result = $this->call_trigger('CATEGORY_DELETE', $user);
635 if ($result < 0) {
636 $error++;
637 }
638 // End call triggers
639 }
640
641 /* FIX #1317 : Check for child category and move up 1 level*/
642 if (!$error) {
643 $sql = "UPDATE ".MAIN_DB_PREFIX."categorie";
644 $sql .= " SET fk_parent = ".((int) $this->fk_parent);
645 $sql .= " WHERE fk_parent = ".((int) $this->id);
646
647 if (!$this->db->query($sql)) {
648 $this->error = $this->db->lasterror();
649 $error++;
650 }
651 }
652
653 $arraydelete = array(
654 'categorie_account' => 'fk_categorie',
655 'categorie_actioncomm' => 'fk_categorie',
656 'categorie_contact' => 'fk_categorie',
657 'categorie_fournisseur' => 'fk_categorie',
658 'categorie_knowledgemanagement' => array('field' => 'fk_categorie', 'enabled' => isModEnabled('knowledgemanagement')),
659 'categorie_member' => 'fk_categorie',
660 'categorie_user' => 'fk_categorie',
661 'categorie_product' => 'fk_categorie',
662 'categorie_project' => 'fk_categorie',
663 'categorie_societe' => 'fk_categorie',
664 'categorie_ticket' => array('field' => 'fk_categorie', 'enabled' => isModEnabled('ticket')),
665 'categorie_warehouse' => 'fk_categorie',
666 'categorie_website_page' => array('field' => 'fk_categorie', 'enabled' => isModEnabled('website')),
667 'bank_class' => 'fk_categ',
668 'categorie_lang' => 'fk_category',
669 'categorie' => 'rowid',
670 );
671 foreach ($arraydelete as $key => $value) {
672 if (is_array($value)) {
673 if (empty($value['enabled'])) {
674 continue;
675 }
676 $value = $value['field'];
677 }
678 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$key;
679 $sql .= " WHERE ".$value." = ".((int) $this->id);
680 if (!$this->db->query($sql)) {
681 $this->errors[] = $this->db->lasterror();
682 dol_syslog("Error sql=".$sql." ".$this->error, LOG_ERR);
683 $error++;
684 }
685 }
686
687 // Removed extrafields
688 if (!$error) {
689 $result = $this->deleteExtraFields();
690 if ($result < 0) {
691 $error++;
692 dol_syslog(get_class($this)."::delete erreur ".$this->error, LOG_ERR);
693 }
694 }
695
696 if (!$error) {
697 $this->db->commit();
698 return 1;
699 } else {
700 $this->db->rollback();
701 return -1;
702 }
703 }
704
705 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
714 public function add_type($obj, $type = '')
715 {
716 // phpcs:enable
717 global $user;
718
719 $error = 0;
720
721 if ($this->id == -1) {
722 return -2;
723 }
724
725 if (empty($type)) {
726 $type = $obj->element;
727 }
728
729 dol_syslog(get_class($this).'::add_type', LOG_DEBUG);
730
731 $this->db->begin();
732
733 $sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type]);
734 $sql .= " (fk_categorie, fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type]).")";
735 $sql .= " VALUES (".((int) $this->id).", ".((int) $obj->id).")";
736
737 if ($this->db->query($sql)) {
738 if (getDolGlobalString('CATEGORIE_RECURSIV_ADD')) {
739 $sql = 'SELECT fk_parent FROM '.MAIN_DB_PREFIX.'categorie';
740 $sql .= " WHERE rowid = ".((int) $this->id);
741
742 dol_syslog(get_class($this)."::add_type", LOG_DEBUG);
743 $resql = $this->db->query($sql);
744 if ($resql) {
745 if ($this->db->num_rows($resql) > 0) {
746 $objparent = $this->db->fetch_object($resql);
747
748 if (!empty($objparent->fk_parent)) {
749 $cat = new Categorie($this->db);
750 $cat->id = $objparent->fk_parent;
751 if (!$cat->containsObject($type, $obj->id)) {
752 $result = $cat->add_type($obj, $type);
753 if ($result < 0) {
754 $this->error = $cat->error;
755 $error++;
756 }
757 }
758 }
759 }
760 } else {
761 $error++;
762 $this->error = $this->db->lasterror();
763 }
764
765 if ($error) {
766 $this->db->rollback();
767 return -1;
768 }
769 }
770
771 // Call trigger
772 $this->context = array('linkto'=>$obj); // Save object we want to link category to into category instance to provide information to trigger
773 $result = $this->call_trigger('CATEGORY_LINK', $user);
774 if ($result < 0) {
775 $error++;
776 }
777 // End call triggers
778
779 if (!$error) {
780 $this->db->commit();
781 return 1;
782 } else {
783 $this->db->rollback();
784 return -2;
785 }
786 } else {
787 $this->db->rollback();
788 if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
789 $this->error = $this->db->lasterrno();
790 return -3;
791 } else {
792 $this->error = $this->db->lasterror();
793 }
794 return -1;
795 }
796 }
797
798 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
807 public function del_type($obj, $type)
808 {
809 // phpcs:enable
810 global $user;
811
812 $error = 0;
813
814 // For backward compatibility
815 if ($type == 'societe') {
816 $type = 'customer';
817 dol_syslog(get_class($this)."::del_type(): type 'societe' is deprecated, please use 'customer' instead", LOG_WARNING);
818 } elseif ($type == 'fournisseur') {
819 $type = 'supplier';
820 dol_syslog(get_class($this)."::del_type(): type 'fournisseur' is deprecated, please use 'supplier' instead", LOG_WARNING);
821 }
822
823 $this->db->begin();
824
825 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type]);
826 $sql .= " WHERE fk_categorie = ".((int) $this->id);
827 $sql .= " AND fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = ".((int) $obj->id);
828
829 dol_syslog(get_class($this).'::del_type', LOG_DEBUG);
830 if ($this->db->query($sql)) {
831 // Call trigger
832 $this->context = array('unlinkoff'=>$obj); // Save object we want to link category to into category instance to provide information to trigger
833 $result = $this->call_trigger('CATEGORY_UNLINK', $user);
834 if ($result < 0) {
835 $error++;
836 }
837 // End call triggers
838
839 if (!$error) {
840 $this->db->commit();
841 return 1;
842 } else {
843 $this->db->rollback();
844 return -2;
845 }
846 } else {
847 $this->db->rollback();
848 $this->error = $this->db->lasterror();
849 return -1;
850 }
851 }
852
867 public function getObjectsInCateg($type, $onlyids = 0, $limit = 0, $offset = 0, $sortfield = '', $sortorder = 'ASC', $filter = array(), $filtermode = 'AND')
868 {
869 global $user;
870
871 $objs = array();
872
873 $classnameforobj = $this->MAP_OBJ_CLASS[$type];
874 $obj = new $classnameforobj($this->db);
875
876 $sql = "SELECT c.fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type]);
877 $sql .= " FROM ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type])." as c";
878 $sql .= ", ".MAIN_DB_PREFIX.(empty($this->MAP_OBJ_TABLE[$type]) ? $type : $this->MAP_OBJ_TABLE[$type])." as o";
879 $sql .= " WHERE o.entity IN (".getEntity($obj->element).")";
880 $sql .= " AND c.fk_categorie = ".((int) $this->id);
881 // Compatibility with actioncomm table which has id instead of rowid
882 if ((array_key_exists($type, $this->MAP_OBJ_TABLE) && $this->MAP_OBJ_TABLE[$type] == "actioncomm") || $type == "actioncomm") {
883 $sql .= " AND c.fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = o.id";
884 } else {
885 $sql .= " AND c.fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = o.rowid";
886 }
887 // Protection for external users
888 if (($type == 'customer' || $type == 'supplier') && $user->socid > 0) {
889 $sql .= " AND o.rowid = ".((int) $user->socid);
890 }
891 // Manage filter
892 $sqlwhere = array();
893 if (count($filter) > 0) {
894 foreach ($filter as $key => $value) {
895 if ($key == 'o.rowid') {
896 $sqlwhere[] = $key." = ".((int) $value);
897 } elseif ($key == 'customsql') {
898 $sqlwhere[] = $value;
899 }
900 }
901 }
902 if (count($sqlwhere) > 0) {
903 $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
904 }
905 $sql .= $this->db->order($sortfield, $sortorder);
906 if ($limit > 0 || $offset > 0) {
907 $sql .= $this->db->plimit($limit + 1, $offset);
908 }
909
910 dol_syslog(get_class($this)."::getObjectsInCateg", LOG_DEBUG);
911
912 $resql = $this->db->query($sql);
913 if ($resql) {
914 while ($rec = $this->db->fetch_array($resql)) {
915 if ($onlyids) {
916 $objs[] = $rec['fk_'.(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])];
917 } else {
918 $classnameforobj = $this->MAP_OBJ_CLASS[$type];
919
920 $obj = new $classnameforobj($this->db);
921 $obj->fetch($rec['fk_'.(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])]);
922
923 $objs[] = $obj;
924 }
925 }
926 return $objs;
927 } else {
928 $this->error = $this->db->error().' sql='.$sql;
929 return -1;
930 }
931 }
932
941 public function containsObject($type, $object_id)
942 {
943 $sql = "SELECT COUNT(*) as nb FROM ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type]);
944 $sql .= " WHERE fk_categorie = ".((int) $this->id)." AND fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = ".((int) $object_id);
945
946 dol_syslog(get_class($this)."::containsObject", LOG_DEBUG);
947
948 $resql = $this->db->query($sql);
949 if ($resql) {
950 return $this->db->fetch_object($resql)->nb;
951 } else {
952 $this->error = $this->db->error();
953 return -1;
954 }
955 }
956
968 public function getListForItem($id, $type = 'customer', $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
969 {
970 $categories = array();
971
972 $type = sanitizeVal($type, 'aZ09');
973
974 $sub_type = $type;
975 $subcol_name = "fk_".$type;
976 if ($type == "customer") {
977 $sub_type = "societe";
978 $subcol_name = "fk_soc";
979 }
980 if ($type == "supplier") {
981 $sub_type = "fournisseur";
982 $subcol_name = "fk_soc";
983 }
984 if ($type == "contact") {
985 $subcol_name = "fk_socpeople";
986 }
987
988 $idoftype = array_search($type, self::$MAP_ID_TO_CODE);
989
990 $sql = "SELECT s.rowid";
991 $sql .= " FROM ".MAIN_DB_PREFIX."categorie as s, ".MAIN_DB_PREFIX."categorie_".$sub_type." as sub";
992 $sql .= ' WHERE s.entity IN ('.getEntity('category').')';
993 $sql .= ' AND s.type='.((int) $idoftype);
994 $sql .= ' AND s.rowid = sub.fk_categorie';
995 $sql .= " AND sub.".$subcol_name." = ".((int) $id);
996
997 $sql .= $this->db->order($sortfield, $sortorder);
998
999 $offset = 0;
1000 $nbtotalofrecords = '';
1001 if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
1002 $result = $this->db->query($sql);
1003 $nbtotalofrecords = $this->db->num_rows($result);
1004 if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
1005 $page = 0;
1006 $offset = 0;
1007 }
1008 }
1009
1010 if ($limit) {
1011 if ($page < 0) {
1012 $page = 0;
1013 }
1014 $offset = $limit * $page;
1015
1016 $sql .= $this->db->plimit($limit + 1, $offset);
1017 }
1018
1019 $result = $this->db->query($sql);
1020 if ($result) {
1021 $i = 0;
1022 $num = $this->db->num_rows($result);
1023 $min = min($num, ($limit <= 0 ? $num : $limit));
1024 while ($i < $min) {
1025 $obj = $this->db->fetch_object($result);
1026 $category_static = new Categorie($this->db);
1027 if ($category_static->fetch($obj->rowid)) {
1028 $categories[$i]['id'] = $category_static->id;
1029 $categories[$i]['fk_parent'] = $category_static->fk_parent;
1030 $categories[$i]['label'] = $category_static->label;
1031 $categories[$i]['description'] = $category_static->description;
1032 $categories[$i]['color'] = $category_static->color;
1033 $categories[$i]['socid'] = $category_static->socid;
1034 $categories[$i]['ref_ext'] = $category_static->ref_ext;
1035 $categories[$i]['visible'] = $category_static->visible;
1036 $categories[$i]['type'] = $category_static->type;
1037 $categories[$i]['entity'] = $category_static->entity;
1038 $categories[$i]['array_options'] = $category_static->array_options;
1039
1040 // multilangs
1041 if (getDolGlobalInt('MAIN_MULTILANGS') && isset($category_static->multilangs)) {
1042 $categories[$i]['multilangs'] = $category_static->multilangs;
1043 }
1044 }
1045 $i++;
1046 }
1047 } else {
1048 $this->error = $this->db->lasterror();
1049 return -1;
1050 }
1051 if (!count($categories)) {
1052 return 0;
1053 }
1054
1055 return $categories;
1056 }
1057
1058 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1064 public function get_filles()
1065 {
1066 // phpcs:enable
1067 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
1068 $sql .= " WHERE fk_parent = ".((int) $this->id);
1069 $sql .= " AND entity IN (".getEntity('category').")";
1070
1071 $res = $this->db->query($sql);
1072 if ($res) {
1073 $cats = array();
1074 while ($rec = $this->db->fetch_array($res)) {
1075 $cat = new Categorie($this->db);
1076 $cat->fetch($rec['rowid']);
1077 $cats[] = $cat;
1078 }
1079 return $cats;
1080 } else {
1081 dol_print_error($this->db);
1082 return -1;
1083 }
1084 }
1085
1086 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1092 protected function load_motherof()
1093 {
1094 // phpcs:enable
1095 $this->motherof = array();
1096
1097 // Load array[child]=parent
1098 $sql = "SELECT fk_parent as id_parent, rowid as id_son";
1099 $sql .= " FROM ".MAIN_DB_PREFIX."categorie";
1100 $sql .= " WHERE fk_parent != 0";
1101 $sql .= " AND entity IN (".getEntity('category').")";
1102
1103 dol_syslog(get_class($this)."::load_motherof", LOG_DEBUG);
1104 $resql = $this->db->query($sql);
1105 if ($resql) {
1106 while ($obj = $this->db->fetch_object($resql)) {
1107 $this->motherof[$obj->id_son] = $obj->id_parent;
1108 }
1109 return 1;
1110 } else {
1111 dol_print_error($this->db);
1112 return -1;
1113 }
1114 }
1115
1116 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1136 public function get_full_arbo($type, $markafterid = 0, $include = 0)
1137 {
1138 // phpcs:enable
1139 global $langs;
1140
1141 if (!is_numeric($type)) {
1142 $type = $this->MAP_ID[$type];
1143 }
1144 if (is_null($type)) {
1145 $this->error = 'BadValueForParameterType';
1146 return -1;
1147 }
1148
1149 if (is_string($markafterid)) {
1150 $markafterid = explode(',', $markafterid);
1151 } elseif (is_numeric($markafterid)) {
1152 if ($markafterid > 0) {
1153 $markafterid = array($markafterid);
1154 } else {
1155 $markafterid = array();
1156 }
1157 } elseif (!is_array($markafterid)) {
1158 $markafterid = array();
1159 }
1160
1161 $this->cats = array();
1162 $nbcateg = 0;
1163
1164 // Init this->motherof that is array(id_son=>id_parent, ...)
1165 $this->load_motherof();
1166 $current_lang = $langs->getDefaultLang();
1167
1168 // Init $this->cats array
1169 $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
1170 if (getDolGlobalInt('MAIN_MULTILANGS')) {
1171 $sql .= ", t.label as label_trans, t.description as description_trans";
1172 }
1173 $sql .= " FROM ".MAIN_DB_PREFIX."categorie as c";
1174 if (getDolGlobalInt('MAIN_MULTILANGS')) {
1175 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_lang as t ON t.fk_category=c.rowid AND t.lang='".$this->db->escape($current_lang)."'";
1176 }
1177 $sql .= " WHERE c.entity IN (".getEntity('category').")";
1178 $sql .= " AND c.type = ".(int) $type;
1179
1180 dol_syslog(get_class($this)."::get_full_arbo get category list", LOG_DEBUG);
1181 $resql = $this->db->query($sql);
1182 if ($resql) {
1183 $i = 0;
1184 $nbcateg = $this->db->num_rows($resql);
1185
1186 while ($obj = $this->db->fetch_object($resql)) {
1187 $this->cats[$obj->rowid]['rowid'] = $obj->rowid;
1188 $this->cats[$obj->rowid]['id'] = $obj->rowid;
1189 $this->cats[$obj->rowid]['fk_parent'] = $obj->fk_parent;
1190 $this->cats[$obj->rowid]['label'] = !empty($obj->label_trans) ? $obj->label_trans : $obj->label;
1191 $this->cats[$obj->rowid]['description'] = !empty($obj->description_trans) ? $obj->description_trans : $obj->description;
1192 $this->cats[$obj->rowid]['color'] = $obj->color;
1193 $this->cats[$obj->rowid]['visible'] = $obj->visible;
1194 $this->cats[$obj->rowid]['ref_ext'] = $obj->ref_ext;
1195 $this->cats[$obj->rowid]['picto'] = 'category';
1196 $i++;
1197 }
1198 } else {
1199 dol_print_error($this->db);
1200 return -1;
1201 }
1202
1203 // We add the fullpath property to each elements of first level (no parent exists)
1204 dol_syslog(get_class($this)."::get_full_arbo call to buildPathFromId", LOG_DEBUG);
1205 foreach ($this->cats as $key => $val) {
1206 //print 'key='.$key.'<br>'."\n";
1207 $this->buildPathFromId($key, $nbcateg); // Process a branch from the root category key (this category has no parent)
1208 }
1209
1210 // Include or exclude leaf including $markafterid from tree
1211 if (count($markafterid) > 0) {
1212 $keyfiltercatid = '('.implode('|', $markafterid).')';
1213
1214 //print "Look to discard category ".$markafterid."\n";
1215 $keyfilter1 = '^'.$keyfiltercatid.'$';
1216 $keyfilter2 = '_'.$keyfiltercatid.'$';
1217 $keyfilter3 = '^'.$keyfiltercatid.'_';
1218 $keyfilter4 = '_'.$keyfiltercatid.'_';
1219 foreach ($this->cats as $key => $val) {
1220 $test = (preg_match('/'.$keyfilter1.'/', $val['fullpath']) || preg_match('/'.$keyfilter2.'/', $val['fullpath'])
1221 || preg_match('/'.$keyfilter3.'/', $val['fullpath']) || preg_match('/'.$keyfilter4.'/', $val['fullpath']));
1222
1223 if (($test && !$include) || (!$test && $include)) {
1224 unset($this->cats[$key]);
1225 }
1226 }
1227 }
1228
1229 dol_syslog(get_class($this)."::get_full_arbo dol_sort_array", LOG_DEBUG);
1230 $this->cats = dol_sort_array($this->cats, 'fulllabel', 'asc', true, false);
1231
1232 return $this->cats;
1233 }
1234
1245 private function buildPathFromId($id_categ, $protection = 1000)
1246 {
1247 //dol_syslog(get_class($this)."::buildPathFromId id_categ=".$id_categ." protection=".$protection, LOG_DEBUG);
1248
1249 if (!empty($this->cats[$id_categ]['fullpath'])) {
1250 // Already defined
1251 dol_syslog(get_class($this)."::buildPathFromId fullpath and fulllabel already defined", LOG_WARNING);
1252 return -1;
1253 }
1254
1255 // First build full array $motherof
1256 //$this->load_motherof(); // Disabled because already done by caller of buildPathFromId
1257
1258 // $this->cats[$id_categ] is supposed to be already an array. We just want to complete it with property fullpath and fulllabel
1259
1260 // Define fullpath and fulllabel
1261 $this->cats[$id_categ]['fullpath'] = '_'.$id_categ;
1262 $this->cats[$id_categ]['fulllabel'] = $this->cats[$id_categ]['label'];
1263 $i = 0;
1264 $cursor_categ = $id_categ;
1265 //print 'Work for id_categ='.$id_categ.'<br>'."\n";
1266 while ((empty($protection) || $i < $protection) && !empty($this->motherof[$cursor_categ])) {
1267 //print '&nbsp; cursor_categ='.$cursor_categ.' i='.$i.' '.$this->motherof[$cursor_categ].'<br>'."\n";
1268 $this->cats[$id_categ]['fullpath'] = '_'.$this->motherof[$cursor_categ].$this->cats[$id_categ]['fullpath'];
1269 $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'];
1270 //print '&nbsp; Result for id_categ='.$id_categ.' : '.$this->cats[$id_categ]['fullpath'].' '.$this->cats[$id_categ]['fulllabel'].'<br>'."\n";
1271 $i++;
1272 $cursor_categ = $this->motherof[$cursor_categ];
1273 }
1274 //print 'Result for id_categ='.$id_categ.' : '.$this->cats[$id_categ]['fullpath'].'<br>'."\n";
1275
1276 // We count number of _ to have level
1277 $nbunderscore = substr_count($this->cats[$id_categ]['fullpath'], '_');
1278 $this->cats[$id_categ]['level'] = ($nbunderscore ? $nbunderscore : null);
1279
1280 return 1;
1281 }
1282
1283
1284 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1292 public function get_all_categories($type = null, $parent = false)
1293 {
1294 // phpcs:enable
1295 if (!is_numeric($type)) {
1296 $type = $this->MAP_ID[$type];
1297 }
1298
1299 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
1300 $sql .= " WHERE entity IN (".getEntity('category').")";
1301 if (!is_null($type)) {
1302 $sql .= " AND type = ".(int) $type;
1303 }
1304 if ($parent) {
1305 $sql .= " AND fk_parent = 0";
1306 }
1307
1308 $res = $this->db->query($sql);
1309 if ($res) {
1310 $cats = array();
1311 while ($rec = $this->db->fetch_array($res)) {
1312 $cat = new Categorie($this->db);
1313 $cat->fetch($rec['rowid']);
1314 $cats[$rec['rowid']] = $cat;
1315 }
1316 return $cats;
1317 } else {
1318 dol_print_error($this->db);
1319 return -1;
1320 }
1321 }
1322
1323 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1330 public function get_main_categories($type = null)
1331 {
1332 // phpcs:enable
1333 return $this->get_all_categories($type, true);
1334 }
1335
1336 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1342 public function already_exists()
1343 {
1344 // phpcs:enable
1345 $type = $this->type;
1346
1347 if (!is_numeric($type)) {
1348 $type = $this->MAP_ID[$type];
1349 }
1350
1351 /* We have to select any rowid from llx_categorie which category's mother and label
1352 * are equals to those of the calling category
1353 */
1354 $sql = "SELECT c.rowid";
1355 $sql .= " FROM ".MAIN_DB_PREFIX."categorie as c ";
1356 $sql .= " WHERE c.entity IN (".getEntity('category').")";
1357 $sql .= " AND c.type = ".((int) $type);
1358 $sql .= " AND c.fk_parent = ".((int) $this->fk_parent);
1359 $sql .= " AND c.label = '".$this->db->escape($this->label)."'";
1360
1361 dol_syslog(get_class($this)."::already_exists", LOG_DEBUG);
1362 $resql = $this->db->query($sql);
1363 if ($resql) {
1364 if ($this->db->num_rows($resql) > 0) { // Checking for empty resql
1365 $obj = $this->db->fetch_array($resql);
1366 /* If object called create, obj cannot have is id.
1367 * If object called update, he mustn't have the same label as an other category for this mother.
1368 * So if the result have the same id, update is not for label, and if result have an other one,
1369 * update may be for label.
1370 */
1371 if ($obj[0] > 0 && $obj[0] != $this->id) {
1372 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);
1373 return 1;
1374 }
1375 }
1376 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);
1377 return 0;
1378 } else {
1379 $this->error = $this->db->error();
1380 return -1;
1381 }
1382 }
1383
1384
1385 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1396 public function print_all_ways($sep = '&gt;&gt;', $url = '', $nocolor = 0, $addpicto = 0)
1397 {
1398 // phpcs:enable
1399 $ways = array();
1400
1401 $allways = $this->get_all_ways(); // Load array of categories
1402 foreach ($allways as $way) {
1403 $w = array();
1404 $i = 0;
1405 $forced_color = '';
1406 foreach ($way as $cat) {
1407 $i++;
1408
1409 if (empty($nocolor)) {
1410 $forced_color = 'colortoreplace';
1411 if ($i == count($way)) { // Last category in hierarchy
1412 // Check contrast with background and correct text color
1413 $forced_color = 'categtextwhite';
1414 if ($cat->color) {
1415 if (colorIsLight($cat->color)) {
1416 $forced_color = 'categtextblack';
1417 }
1418 }
1419 }
1420 }
1421
1422 if ($url == '') {
1423 $link = '<a href="'.DOL_URL_ROOT.'/categories/viewcat.php?id='.$cat->id.'&type='.$cat->type.'" class="'.$forced_color.'">';
1424 $linkend = '</a>';
1425 $w[] = $link.(($addpicto && $i == 1) ? img_object('', 'category', 'class="paddingright"') : '').$cat->label.$linkend;
1426 } elseif ($url == 'none') {
1427 $link = '<span class="'.$forced_color.'">';
1428 $linkend = '</span>';
1429 $w[] = $link.(($addpicto && $i == 1) ? img_object('', 'category', 'class="paddingright"') : '').$cat->label.$linkend;
1430 } else {
1431 $w[] = '<a class="'.$forced_color.'" href="'.DOL_URL_ROOT.'/'.$url.'?catid='.$cat->id.'">'.($addpicto ? img_object('', 'category') : '').$cat->label.'</a>';
1432 }
1433 }
1434 $newcategwithpath = preg_replace('/colortoreplace/', $forced_color, implode('<span class="inline-block valignmiddle paddingleft paddingright '.$forced_color.'">'.$sep.'</span>', $w));
1435
1436 $ways[] = $newcategwithpath;
1437 }
1438
1439 return $ways;
1440 }
1441
1442
1443 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1449 public function get_meres()
1450 {
1451 // phpcs:enable
1452 $parents = array();
1453
1454 $sql = "SELECT fk_parent FROM ".MAIN_DB_PREFIX."categorie";
1455 $sql .= " WHERE rowid = ".((int) $this->id);
1456
1457 $res = $this->db->query($sql);
1458
1459 if ($res) {
1460 while ($rec = $this->db->fetch_array($res)) {
1461 if ($rec['fk_parent'] > 0) {
1462 $cat = new Categorie($this->db);
1463 $cat->fetch($rec['fk_parent']);
1464 $parents[] = $cat;
1465 }
1466 }
1467 return $parents;
1468 } else {
1469 dol_print_error($this->db);
1470 return -1;
1471 }
1472 }
1473
1474 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1481 public function get_all_ways()
1482 {
1483 // phpcs:enable
1484 $ways = array();
1485
1486 $parents = $this->get_meres();
1487 if (is_array($parents)) {
1488 foreach ($parents as $parent) {
1489 $allways = $parent->get_all_ways();
1490 foreach ($allways as $way) {
1491 $w = $way;
1492 $w[] = $this;
1493 $ways[] = $w;
1494 }
1495 }
1496 }
1497
1498 if (count($ways) == 0) {
1499 $ways[0][0] = $this;
1500 }
1501
1502 return $ways;
1503 }
1504
1515 public function containing($id, $type, $mode = 'object')
1516 {
1517 $cats = array();
1518
1519 if (is_numeric($type)) {
1520 $type = Categorie::$MAP_ID_TO_CODE[$type];
1521 }
1522
1523 if ($type === Categorie::TYPE_BANK_LINE) { // TODO Remove this with standard category code after migration of llx_bank_categ into llx_categorie
1524 // Load bank categories
1525 $sql = "SELECT c.label, c.rowid";
1526 $sql .= " FROM ".MAIN_DB_PREFIX."bank_class as a, ".MAIN_DB_PREFIX."bank_categ as c";
1527 $sql .= " WHERE a.lineid=".((int) $id)." AND a.fk_categ = c.rowid";
1528 $sql .= " AND c.entity IN (".getEntity('category').")";
1529 $sql .= " ORDER BY c.label";
1530
1531 $res = $this->db->query($sql);
1532 if ($res) {
1533 while ($obj = $this->db->fetch_object($res)) {
1534 if ($mode == 'id') {
1535 $cats[] = $obj->rowid;
1536 } elseif ($mode == 'label') {
1537 $cats[] = $obj->label;
1538 } else {
1539 $cat = new Categorie($this->db);
1540 $cat->id = $obj->rowid;
1541 $cat->label = $obj->label;
1542 $cats[] = $cat;
1543 }
1544 }
1545 } else {
1546 dol_print_error($this->db);
1547 return -1;
1548 }
1549 } else {
1550 $sql = "SELECT ct.fk_categorie, c.label, c.rowid";
1551 $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";
1552 $sql .= " WHERE ct.fk_categorie = c.rowid AND ct.fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type])." = ".(int) $id;
1553 // This seems useless because the table already contains id of category of 1 unique type. So commented.
1554 // So now it works also with external added categories.
1555 //$sql .= " AND c.type = ".((int) $this->MAP_ID[$type]);
1556 $sql .= " AND c.entity IN (".getEntity('category').")";
1557
1558 $res = $this->db->query($sql);
1559 if ($res) {
1560 while ($obj = $this->db->fetch_object($res)) {
1561 if ($mode == 'id') {
1562 $cats[] = $obj->rowid;
1563 } elseif ($mode == 'label') {
1564 $cats[] = $obj->label;
1565 } else {
1566 $cat = new Categorie($this->db);
1567 $cat->fetch($obj->fk_categorie);
1568 $cats[] = $cat;
1569 }
1570 }
1571 } else {
1572 dol_print_error($this->db);
1573 return -1;
1574 }
1575 }
1576
1577 return $cats;
1578 }
1579
1591 public function rechercher($id, $nom, $type, $exact = false, $case = false)
1592 {
1593 // Deprecation warning
1594 if (is_numeric($type)) {
1595 dol_syslog(__METHOD__.': using numeric types is deprecated.', LOG_WARNING);
1596 }
1597
1598 $cats = array();
1599
1600 // For backward compatibility
1601 if (is_numeric($type)) {
1602 // We want to reverse lookup
1603 $map_type = array_flip($this->MAP_ID);
1604 $type = $map_type[$type];
1605 dol_syslog(get_class($this)."::rechercher(): numeric types are deprecated, please use string instead", LOG_WARNING);
1606 }
1607
1608 // Generation requete recherche
1609 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
1610 $sql .= " WHERE type = ".((int) $this->MAP_ID[$type]);
1611 $sql .= " AND entity IN (".getEntity('category').")";
1612 if ($nom) {
1613 if (!$exact) {
1614 $nom = '%'.$this->db->escape(str_replace('*', '%', $nom)).'%';
1615 }
1616 if (!$case) {
1617 $sql .= " AND label LIKE '".$this->db->escape($nom)."'";
1618 } else {
1619 $sql .= " AND label LIKE BINARY '".$this->db->escape($nom)."'";
1620 }
1621 }
1622 if ($id) {
1623 $sql .= " AND rowid = ".((int) $id);
1624 }
1625
1626 $res = $this->db->query($sql);
1627 if ($res) {
1628 while ($rec = $this->db->fetch_array($res)) {
1629 $cat = new Categorie($this->db);
1630 $cat->fetch($rec['rowid']);
1631 $cats[] = $cat;
1632 }
1633
1634 return $cats;
1635 } else {
1636 $this->error = $this->db->error().' sql='.$sql;
1637 return -1;
1638 }
1639 }
1640
1647 public function getTooltipContentArray($params)
1648 {
1649 global $langs;
1650
1651 $langs->load('categories');
1652
1653 $datas = [];
1654
1655 $datas['label'] = $langs->trans("ShowCategory").': '.($this->ref ? $this->ref : $this->label);
1656
1657 return $datas;
1658 }
1659
1673 public function getNomUrl($withpicto = 0, $option = '', $maxlength = 0, $moreparam = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = '')
1674 {
1675 global $conf, $hookmanager;
1676
1677 if (!empty($conf->dol_no_mouse_hover)) {
1678 $notooltip = 1; // Force disable tooltips
1679 }
1680
1681 $result = '';
1682 $params = [
1683 'id' => $this->id,
1684 'objecttype' => $this->element,
1685 'option' => $option,
1686 ];
1687 $classfortooltip = 'classfortooltip';
1688 $dataparams = '';
1689 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1690 $classfortooltip = 'classforajaxtooltip';
1691 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1692 $label = '';
1693 } else {
1694 $label = implode($this->getTooltipContentArray($params));
1695 }
1696
1697 $url = DOL_URL_ROOT.'/categories/viewcat.php?id='.$this->id.'&type='.$this->type.$moreparam.'&backtopage='.urlencode($_SERVER['PHP_SELF'].($moreparam ? '?'.$moreparam : ''));
1698
1699 if ($option !== 'nolink') {
1700 // Add param to save lastsearch_values or not
1701 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1702 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1703 $add_save_lastsearch_values = 1;
1704 }
1705 if ($url && $add_save_lastsearch_values) {
1706 $url .= '&save_lastsearch_values=1';
1707 }
1708 }
1709
1710 // Check contrast with background and correct text color
1711 $forced_color = 'categtextwhite';
1712 if ($this->color) {
1713 if (colorIsLight($this->color)) {
1714 $forced_color = 'categtextblack';
1715 }
1716 }
1717
1718 $linkclose = '';
1719 if (empty($notooltip)) {
1720 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1721 $label = $langs->trans("ShowMyObject");
1722 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1723 }
1724 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1725 $linkclose .= $dataparams.' class="'.$classfortooltip.' '.$forced_color.($morecss ? ' '.$morecss : '').'"';
1726 } else {
1727 $linkclose = ($morecss ? ' class="'.$forced_color.($morecss ? ' '.$morecss : '').'"' : '');
1728 }
1729
1730 if ($option == 'nolink' || empty($url)) {
1731 $linkstart = '<span';
1732 } else {
1733 $linkstart = '<a href="'.$url.'"';
1734 }
1735 $linkstart .= $linkclose.'>';
1736 if ($option == 'nolink' || empty($url)) {
1737 $linkend = '</span>';
1738 } else {
1739 $linkend = '</a>';
1740 }
1741
1742 $result .= $linkstart;
1743
1744 if ($withpicto) {
1745 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1746 }
1747
1748 if ($withpicto != 2) {
1749 $result .= dol_trunc(($this->ref ? $this->ref : $this->label), $maxlength);
1750 }
1751
1752 $result .= $linkend;
1753
1754 global $action;
1755 $hookmanager->initHooks(array($this->element . 'dao'));
1756 $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1757 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1758 if ($reshook > 0) {
1759 $result = $hookmanager->resPrint;
1760 } else {
1761 $result .= $hookmanager->resPrint;
1762 }
1763 return $result;
1764 }
1765
1766
1767 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1775 public function add_photo($sdir, $file)
1776 {
1777 // phpcs:enable
1778 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1779
1780 $dir = $sdir.'/'.get_exdir($this->id, 2, 0, 0, $this, 'category').$this->id."/";
1781 $dir .= "photos/";
1782
1783 if (!file_exists($dir)) {
1784 dol_mkdir($dir);
1785 }
1786
1787 if (file_exists($dir)) {
1788 if (is_array($file['name']) && count($file['name']) > 0) {
1789 $nbfile = count($file['name']);
1790 for ($i = 0; $i <= $nbfile; $i++) {
1791 $originImage = $dir.$file['name'][$i];
1792
1793 // Cree fichier en taille origine
1794 dol_move_uploaded_file($file['tmp_name'][$i], $originImage, 1, 0, 0);
1795
1796 if (file_exists($originImage)) {
1797 // Create thumbs
1798 $this->addThumbs($originImage);
1799 }
1800 }
1801 } else {
1802 $originImage = $dir.$file['name'];
1803
1804 // Cree fichier en taille origine
1805 dol_move_uploaded_file($file['tmp_name'], $originImage, 1, 0, 0);
1806
1807 if (file_exists($originImage)) {
1808 // Create thumbs
1809 $this->addThumbs($originImage);
1810 }
1811 }
1812 }
1813 }
1814
1815 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1823 public function liste_photos($dir, $nbmax = 0)
1824 {
1825 // phpcs:enable
1826 include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1827
1828 $nbphoto = 0;
1829 $tabobj = array();
1830
1831 $dirthumb = $dir.'thumbs/';
1832
1833 if (file_exists($dir)) {
1834 $handle = opendir($dir);
1835 if (is_resource($handle)) {
1836 while (($file = readdir($handle)) !== false) {
1837 if (dol_is_file($dir.$file) && preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i', $dir.$file)) {
1838 $nbphoto++;
1839 $photo = $file;
1840
1841 // On determine nom du fichier vignette
1842 $photo_vignette = '';
1843 $regs = array();
1844 if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i', $photo, $regs)) {
1845 $photo_vignette = preg_replace('/'.$regs[0].'/i', '', $photo).'_small'.$regs[0];
1846 }
1847
1848 // Objet
1849 $obj = array();
1850 $obj['photo'] = $photo;
1851 if ($photo_vignette && is_file($dirthumb.$photo_vignette)) {
1852 $obj['photo_vignette'] = 'thumbs/'.$photo_vignette;
1853 } else {
1854 $obj['photo_vignette'] = "";
1855 }
1856
1857 $tabobj[$nbphoto - 1] = $obj;
1858
1859 // On continue ou on arrete de boucler
1860 if ($nbmax && $nbphoto >= $nbmax) {
1861 break;
1862 }
1863 }
1864 }
1865
1866 closedir($handle);
1867 }
1868 }
1869
1870 return $tabobj;
1871 }
1872
1873 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1880 public function delete_photo($file)
1881 {
1882 // phpcs:enable
1883 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1884
1885 $dir = dirname($file).'/'; // Chemin du dossier contenant l'image d'origine
1886 $dirthumb = $dir.'/thumbs/'; // Chemin du dossier contenant la vignette
1887 $filename = preg_replace('/'.preg_quote($dir, '/').'/i', '', $file); // Nom du fichier
1888
1889 // On efface l'image d'origine
1890 dol_delete_file($file, 1);
1891
1892 // Si elle existe, on efface la vignette
1893 $regs = array();
1894 if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i', $filename, $regs)) {
1895 $photo_vignette = preg_replace('/'.$regs[0].'/i', '', $filename).'_small'.$regs[0];
1896 if (file_exists($dirthumb.$photo_vignette)) {
1897 dol_delete_file($dirthumb.$photo_vignette, 1);
1898 }
1899 }
1900 }
1901
1902 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1909 public function get_image_size($file)
1910 {
1911 // phpcs:enable
1912 $infoImg = getimagesize($file); // Recuperation des infos de l'image
1913 $this->imgWidth = $infoImg[0]; // Largeur de l'image
1914 $this->imgHeight = $infoImg[1]; // Hauteur de l'image
1915 }
1916
1925 public function setMultiLangs(User $user, $notrigger = 0)
1926 {
1927 global $langs;
1928
1929 $langs_available = $langs->get_available_languages();
1930 $current_lang = $langs->getDefaultLang();
1931
1932 foreach ($langs_available as $key => $value) {
1933 $sql = "SELECT rowid";
1934 $sql .= " FROM ".MAIN_DB_PREFIX."categorie_lang";
1935 $sql .= " WHERE fk_category=".((int) $this->id);
1936 $sql .= " AND lang = '".$this->db->escape($key)."'";
1937
1938 $result = $this->db->query($sql);
1939
1940 if ($key == $current_lang) {
1941 if ($this->db->num_rows($result)) { // si aucune ligne dans la base
1942 $sql2 = "UPDATE ".MAIN_DB_PREFIX."categorie_lang";
1943 $sql2 .= " SET label = '".$this->db->escape($this->label)."',";
1944 $sql2 .= " description = '".$this->db->escape($this->description)."'";
1945 $sql2 .= " WHERE fk_category = ".((int) $this->id)." AND lang = '".$this->db->escape($key)."'";
1946 } else {
1947 $sql2 = "INSERT INTO ".MAIN_DB_PREFIX."categorie_lang (fk_category, lang, label, description)";
1948 $sql2 .= " VALUES(".((int) $this->id).", '".$this->db->escape($key)."', '".$this->db->escape($this->label)."'";
1949 $sql2 .= ", '".$this->db->escape($this->multilangs[$key]["description"])."')";
1950 }
1951 dol_syslog(get_class($this).'::setMultiLangs', LOG_DEBUG);
1952 if (!$this->db->query($sql2)) {
1953 $this->error = $this->db->lasterror();
1954 return -1;
1955 }
1956 } elseif (isset($this->multilangs[$key])) {
1957 if ($this->db->num_rows($result)) { // si aucune ligne dans la base
1958 $sql2 = "UPDATE ".MAIN_DB_PREFIX."categorie_lang";
1959 $sql2 .= " SET label='".$this->db->escape($this->multilangs[$key]["label"])."',";
1960 $sql2 .= " description='".$this->db->escape($this->multilangs[$key]["description"])."'";
1961 $sql2 .= " WHERE fk_category=".((int) $this->id)." AND lang='".$this->db->escape($key)."'";
1962 } else {
1963 $sql2 = "INSERT INTO ".MAIN_DB_PREFIX."categorie_lang (fk_category, lang, label, description)";
1964 $sql2 .= " VALUES(".((int) $this->id).", '".$this->db->escape($key)."', '".$this->db->escape($this->multilangs[$key]["label"])."'";
1965 $sql2 .= ",'".$this->db->escape($this->multilangs[$key]["description"])."')";
1966 }
1967
1968 // on ne sauvegarde pas des champs vides
1969 if ($this->multilangs[$key]["label"] || $this->multilangs[$key]["description"] || $this->multilangs[$key]["note"]) {
1970 dol_syslog(get_class($this).'::setMultiLangs', LOG_DEBUG);
1971 }
1972 if (!$this->db->query($sql2)) {
1973 $this->error = $this->db->lasterror();
1974 return -1;
1975 }
1976 }
1977 }
1978
1979 // Call trigger
1980 if (!$notrigger) {
1981 $result = $this->call_trigger('CATEGORY_SET_MULTILANGS', $user);
1982 if ($result < 0) {
1983 $this->error = $this->db->lasterror();
1984 return -1;
1985 }
1986 }
1987 // End call triggers
1988
1989 return 1;
1990 }
1991
1997 public function getMultiLangs()
1998 {
1999 global $langs;
2000
2001 $current_lang = $langs->getDefaultLang();
2002
2003 $sql = "SELECT lang, label, description";
2004 $sql .= " FROM ".MAIN_DB_PREFIX."categorie_lang";
2005 $sql .= " WHERE fk_category=".((int) $this->id);
2006
2007 $result = $this->db->query($sql);
2008 if ($result) {
2009 while ($obj = $this->db->fetch_object($result)) {
2010 //print 'lang='.$obj->lang.' current='.$current_lang.'<br>';
2011 if ($obj->lang == $current_lang) { // si on a les traduct. dans la langue courante on les charge en infos principales.
2012 $this->label = $obj->label;
2013 $this->description = $obj->description;
2014 }
2015 $this->multilangs[$obj->lang]["label"] = $obj->label;
2016 $this->multilangs[$obj->lang]["description"] = $obj->description;
2017 }
2018 return 1;
2019 } else {
2020 $this->error = $langs->trans("Error")." : ".$this->db->error()." - ".$sql;
2021 return -1;
2022 }
2023 }
2024
2031 public function getLibStatut($mode)
2032 {
2033 return '';
2034 }
2035
2036
2044 public function initAsSpecimen()
2045 {
2046 dol_syslog(get_class($this)."::initAsSpecimen");
2047
2048 // Initialise parametres
2049 $this->id = 0;
2050 $this->fk_parent = 0;
2051 $this->label = 'SPECIMEN';
2052 $this->specimen = 1;
2053 $this->description = 'This is a description';
2054 $this->socid = 1;
2055 $this->type = self::TYPE_PRODUCT;
2056 }
2057
2066 public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
2067 {
2068 $tables = array(
2069 'categorie_societe'
2070 );
2071
2072 return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables, 1);
2073 }
2074
2083 public static function getFilterJoinQuery($type, $rowIdName)
2084 {
2085 if ($type == 'bank_account') {
2086 $type = 'account';
2087 }
2088
2089 return " LEFT JOIN ".MAIN_DB_PREFIX."categorie_".$type." as cp ON ".$rowIdName." = cp.fk_".$type;
2090 }
2091
2101 public static function getFilterSelectQuery($type, $rowIdName, $searchList)
2102 {
2103 if ($type == 'bank_account') {
2104 $type = 'account';
2105 }
2106 if ($type == 'customer') {
2107 $type = 'societe';
2108 }
2109 if ($type == 'supplier') {
2110 $type = 'fournisseur';
2111 }
2112
2113 if (empty($searchList) && !is_array($searchList)) {
2114 return "";
2115 }
2116
2117 $searchCategorySqlList = array();
2118 foreach ($searchList as $searchCategory) {
2119 if (intval($searchCategory) == -2) {
2120 $searchCategorySqlList[] = " cp.fk_categorie IS NULL";
2121 } elseif (intval($searchCategory) > 0) {
2122 $searchCategorySqlList[] = " ".$rowIdName." IN (SELECT fk_".$type." FROM ".MAIN_DB_PREFIX."categorie_".$type." WHERE fk_categorie = ".((int) $searchCategory).")";
2123 }
2124 }
2125
2126 if (!empty($searchCategorySqlList)) {
2127 return " AND (".implode(' AND ', $searchCategorySqlList).")";
2128 } else {
2129 return "";
2130 }
2131 }
2132
2138 public function countNbOfCategories()
2139 {
2140 dol_syslog(get_class($this)."::count_all_categories", LOG_DEBUG);
2141 $sql = "SELECT COUNT(rowid) FROM ".MAIN_DB_PREFIX."categorie";
2142 $sql .= " WHERE entity IN (".getEntity('category').")";
2143
2144 $res = $this->db->query($sql);
2145 if ($res) {
2146 $obj = $this->db->fetch_object($res);
2147 return $obj->count;
2148 } else {
2149 dol_print_error($this->db);
2150 return -1;
2151 }
2152 }
2153}
$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.
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, ...)
getNomUrl($withpicto=0, $option='', $maxlength=0, $moreparam='', $notooltip=0, $morecss='', $save_lastsearch_value='')
Return name and link of category (with picto) Use ->id, ->ref, ->label, ->color.
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.
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.
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.
setMultiLangs(User $user, $notrigger=0)
Update ou cree les traductions des infos produits.
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.
update(User $user, $notrigger=0)
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...
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 a 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.
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.
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:121