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