dolibarr  9.0.0
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 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 <http://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.'/fourn/class/fournisseur.class.php';
38 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
39 
40 
44 class Categorie extends CommonObject
45 {
46  // Categories types (we use string because we want to accept any modules/types in a future)
47  const TYPE_PRODUCT = 'product';
48  const TYPE_SUPPLIER = 'supplier';
49  const TYPE_CUSTOMER = 'customer';
50  const TYPE_MEMBER = 'member';
51  const TYPE_CONTACT = 'contact';
52  const TYPE_USER = 'user';
53  const TYPE_PROJECT = 'project';
54  const TYPE_ACCOUNT = 'bank_account';
55  const TYPE_BANK_LINE = 'bank_line';
56 
60  public $picto = 'category';
61 
62 
68  private $MAP_ID = array(
69  'product' => 0,
70  'supplier' => 1,
71  'customer' => 2,
72  'member' => 3,
73  'contact' => 4,
74  'bank_account' => 5,
75  'project' => 6,
76  'user' => 7,
77  'bank_line' => 8,
78  );
79 
83  public static $MAP_ID_TO_CODE = array(
84  0 => 'product',
85  1 => 'supplier',
86  2 => 'customer',
87  3 => 'member',
88  4 => 'contact',
89  5 => 'bank_account',
90  6 => 'project',
91  7 => 'user',
92  8 => 'bank_line',
93  );
94 
100  private $MAP_CAT_FK = array(
101  'product' => 'product',
102  'customer' => 'soc',
103  'supplier' => 'soc',
104  'member' => 'member',
105  'contact' => 'socpeople',
106  'user' => 'user',
107  'account' => 'account', // old for bank_account
108  'bank_account' => 'account',
109  'project' => 'project',
110  );
111 
117  private $MAP_CAT_TABLE = array(
118  'product' => 'product',
119  'customer' => 'societe',
120  'supplier' => 'fournisseur',
121  'member' => 'member',
122  'contact' => 'contact',
123  'user' => 'user',
124  'account' => 'account', // old for bank_account
125  'bank_account'=> 'account',
126  'project' => 'project',
127  );
128 
134  private $MAP_OBJ_CLASS = array(
135  'product' => 'Product',
136  'customer' => 'Societe',
137  'supplier' => 'Fournisseur',
138  'member' => 'Adherent',
139  'contact' => 'Contact',
140  'user' => 'User',
141  'account' => 'Account', // old for bank account
142  'bank_account' => 'Account',
143  'project' => 'Project',
144  );
145 
151  private $MAP_OBJ_TABLE = array(
152  'product' => 'product',
153  'customer' => 'societe',
154  'supplier' => 'societe',
155  'member' => 'adherent',
156  'contact' => 'socpeople',
157  'user' => 'user',
158  'account' => 'bank_account',
159  'project' => 'projet',
160  );
161 
165  public $element='category';
166 
170  public $table_element='categorie';
171 
175  public $fk_parent;
176 
180  public $label;
181 
185  public $description;
186 
190  public $color;
194  public $socid;
207  public $type;
208 
212  public $cats = array();
213 
217  public $motherof = array();
218 
224  function __construct($db)
225  {
226  $this->db = $db;
227  }
228 
237  function fetch($id, $label='', $type=null)
238  {
239  global $conf;
240 
241  // Check parameters
242  if (empty($id) && empty($label)) return -1;
243  if (! is_numeric($type)) $type=$this->MAP_ID[$type];
244 
245  $sql = "SELECT rowid, fk_parent, entity, label, description, color, fk_soc, visible, type";
246  $sql.= " FROM ".MAIN_DB_PREFIX."categorie";
247  if ($id > 0)
248  {
249  $sql.= " WHERE rowid = ".$id;
250  }
251  else
252  {
253  $sql.= " WHERE label = '".$this->db->escape($label)."' AND entity IN (".getEntity('category').")";
254  if (! is_null($type)) $sql.= " AND type = ".$this->db->escape($type);
255  }
256 
257  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
258  $resql = $this->db->query($sql);
259  if ($resql)
260  {
261  if ($this->db->num_rows($resql) > 0)
262  {
263  $res = $this->db->fetch_array($resql);
264 
265  $this->id = $res['rowid'];
266  //$this->ref = $res['rowid'];
267  $this->fk_parent = $res['fk_parent'];
268  $this->label = $res['label'];
269  $this->description = $res['description'];
270  $this->color = $res['color'];
271  $this->socid = $res['fk_soc'];
272  $this->visible = $res['visible'];
273  $this->type = $res['type'];
274  $this->entity = $res['entity'];
275 
276  // Retreive all extrafield
277  // fetch optionals attributes and labels
278  $this->fetch_optionals();
279 
280  $this->db->free($resql);
281 
282  // multilangs
283  if (! empty($conf->global->MAIN_MULTILANGS)) $this->getMultiLangs();
284 
285  return 1;
286  }
287  else
288  {
289  return 0;
290  }
291  }
292  else
293  {
294  dol_print_error($this->db);
295  return -1;
296  }
297  }
298 
308  function create($user)
309  {
310  global $conf,$langs,$hookmanager;
311  $langs->load('categories');
312 
313  $type=$this->type;
314 
315  if (! is_numeric($type)) $type=$this->MAP_ID[$type];
316 
317  $error=0;
318 
319  dol_syslog(get_class($this).'::create', LOG_DEBUG);
320 
321  // Clean parameters
322  $this->label = trim($this->label);
323  $this->description = trim($this->description);
324  $this->color = trim($this->color);
325  $this->import_key = trim($this->import_key);
326  if (empty($this->visible)) $this->visible=0;
327  $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
328 
329  if ($this->already_exists())
330  {
331  $this->error=$langs->trans("ImpossibleAddCat", $this->label);
332  $this->error.=" : ".$langs->trans("CategoryExistsAtSameLevel");
333  dol_syslog($this->error, LOG_WARNING);
334  return -4;
335  }
336 
337  $this->db->begin();
338 
339  $sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie (";
340  $sql.= "fk_parent,";
341  $sql.= " label,";
342  $sql.= " description,";
343  $sql.= " color,";
344  if (! empty($conf->global->CATEGORY_ASSIGNED_TO_A_CUSTOMER))
345  {
346  $sql.= "fk_soc,";
347  }
348  $sql.= " visible,";
349  $sql.= " type,";
350  $sql.= " import_key,";
351  $sql.= " entity";
352  $sql.= ") VALUES (";
353  $sql.= $this->db->escape($this->fk_parent).",";
354  $sql.= "'".$this->db->escape($this->label)."',";
355  $sql.= "'".$this->db->escape($this->description)."',";
356  $sql.= "'".$this->db->escape($this->color)."',";
357  if (! empty($conf->global->CATEGORY_ASSIGNED_TO_A_CUSTOMER))
358  {
359  $sql.= ($this->socid != -1 ? $this->socid : 'null').",";
360  }
361  $sql.= "'".$this->db->escape($this->visible)."',";
362  $sql.= $this->db->escape($type).",";
363  $sql.= (! empty($this->import_key)?"'".$this->db->escape($this->import_key)."'":'null').",";
364  $sql.= $this->db->escape($conf->entity);
365  $sql.= ")";
366 
367  $res = $this->db->query($sql);
368  if ($res)
369  {
370  $id = $this->db->last_insert_id(MAIN_DB_PREFIX."categorie");
371 
372  if ($id > 0)
373  {
374  $this->id = $id;
375 
376  $action='create';
377 
378  // Actions on extra fields
379  if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
380  {
381  $result=$this->insertExtraFields();
382  if ($result < 0)
383  {
384  $error++;
385  }
386  }
387 
388  if (! $error)
389  {
390  // Call trigger
391  $result=$this->call_trigger('CATEGORY_CREATE',$user);
392  if ($result < 0) { $error++; }
393  // End call triggers
394  }
395 
396  if ( ! $error )
397  {
398  $this->db->commit();
399  return $id;
400  }
401  else
402  {
403  $this->db->rollback();
404  return -3;
405  }
406  }
407  else
408  {
409  $this->db->rollback();
410  return -2;
411  }
412  }
413  else
414  {
415  $this->error=$this->db->error();
416  $this->db->rollback();
417  return -1;
418  }
419  }
420 
429  function update(User $user)
430  {
431  global $conf, $langs,$hookmanager;
432 
433  $error=0;
434 
435  // Clean parameters
436  $this->label=trim($this->label);
437  $this->description=trim($this->description);
438  $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
439  $this->visible = ($this->visible != "" ? intval($this->visible) : 0);
440 
441  if ($this->already_exists())
442  {
443  $this->error=$langs->trans("ImpossibleUpdateCat");
444  $this->error.=" : ".$langs->trans("CategoryExistsAtSameLevel");
445  return -1;
446  }
447 
448  $this->db->begin();
449 
450  $sql = "UPDATE ".MAIN_DB_PREFIX."categorie";
451  $sql.= " SET label = '".$this->db->escape($this->label)."',";
452  $sql.= " description = '".$this->db->escape($this->description)."',";
453  $sql.= " color = '".$this->db->escape($this->color)."'";
454  if (! empty($conf->global->CATEGORY_ASSIGNED_TO_A_CUSTOMER))
455  {
456  $sql .= ", fk_soc = ".($this->socid != -1 ? $this->socid : 'null');
457  }
458  $sql .= ", visible = '".$this->db->escape($this->visible)."'";
459  $sql .= ", fk_parent = ".$this->fk_parent;
460  $sql .= " WHERE rowid = ".$this->id;
461 
462  dol_syslog(get_class($this)."::update", LOG_DEBUG);
463  if ($this->db->query($sql))
464  {
465  $action='update';
466 
467  // Actions on extra fields
468  if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
469  {
470  $result=$this->insertExtraFields();
471  if ($result < 0)
472  {
473  $error++;
474  }
475  }
476 
477  if (! $error)
478  {
479  // Call trigger
480  $result=$this->call_trigger('CATEGORY_MODIFY',$user);
481  if ($result < 0) { $error++; $this->db->rollback(); return -1; }
482  // End call triggers
483  }
484 
485  $this->db->commit();
486 
487  return 1;
488  }
489  else
490  {
491  $this->db->rollback();
492  dol_print_error($this->db);
493  return -1;
494  }
495  }
496 
504  function delete($user, $notrigger=0)
505  {
506  global $conf,$langs;
507 
508  $error=0;
509 
510  // Clean parameters
511  $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
512 
513  dol_syslog(get_class($this)."::remove");
514 
515  $this->db->begin();
516 
517  if (! $error && ! $notrigger)
518  {
519  // Call trigger
520  $result=$this->call_trigger('CATEGORY_DELETE',$user);
521  if ($result < 0) $error++;
522  // End call triggers
523  }
524 
525  /* FIX #1317 : Check for child category and move up 1 level*/
526  if (! $error)
527  {
528  $sql = "UPDATE ".MAIN_DB_PREFIX."categorie";
529  $sql.= " SET fk_parent = ".$this->fk_parent;
530  $sql.= " WHERE fk_parent = ".$this->id;
531 
532  if (!$this->db->query($sql))
533  {
534  $this->error=$this->db->lasterror();
535  $error++;
536  }
537  }
538 
539  $arraydelete = array(
540  'categorie_societe' => 'fk_categorie',
541  'categorie_fournisseur' => 'fk_categorie',
542  'categorie_product' => 'fk_categorie',
543  'categorie_member' => 'fk_categorie',
544  'categorie_contact' => 'fk_categorie',
545  'categorie_account' => 'fk_categorie',
546  'bank_class' => 'fk_categ',
547  'categorie_lang' => 'fk_category',
548  'categorie' => 'rowid',
549  );
550  foreach ($arraydelete as $key => $value) {
551  $sql = "DELETE FROM " . MAIN_DB_PREFIX . $key;
552  $sql .= " WHERE ".$value." = ".$this->id;
553  if (!$this->db->query($sql)) {
554  $this->errors[] = $this->db->lasterror();
555  dol_syslog("Error sql=".$sql." ".$this->error, LOG_ERR);
556  $error++;
557  }
558  }
559 
560  // Removed extrafields
561  if (! $error && empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
562  {
563  $result=$this->deleteExtraFields();
564  if ($result < 0)
565  {
566  $error++;
567  dol_syslog(get_class($this)."::delete erreur ".$this->error, LOG_ERR);
568  }
569  }
570 
571  if (! $error)
572  {
573  $this->db->commit();
574  return 1;
575  }
576  else
577  {
578  $this->db->rollback();
579  return -1;
580  }
581  }
582 
583  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
591  function add_type($obj, $type)
592  {
593  // phpcs:enable
594  global $user,$langs,$conf;
595 
596  $error=0;
597 
598  if ($this->id == -1) return -2;
599 
600  $this->db->begin();
601 
602  $sql = "INSERT INTO " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type];
603  $sql .= " (fk_categorie, fk_" . $this->MAP_CAT_FK[$type] . ")";
604  $sql .= " VALUES (" . $this->id . ", " . $obj->id . ")";
605 
606  dol_syslog(get_class($this).'::add_type', LOG_DEBUG);
607  if ($this->db->query($sql))
608  {
609  if (! empty($conf->global->CATEGORIE_RECURSIV_ADD))
610  {
611  $sql = 'SELECT fk_parent FROM '.MAIN_DB_PREFIX.'categorie';
612  $sql.= " WHERE rowid = ".$this->id;
613 
614  dol_syslog(get_class($this)."::add_type", LOG_DEBUG);
615  $resql=$this->db->query($sql);
616  if ($resql)
617  {
618  if ($this->db->num_rows($resql) > 0)
619  {
620  $objparent = $this->db->fetch_object($resql);
621 
622  if (!empty($objparent->fk_parent))
623  {
624  $cat = new Categorie($this->db);
625  $cat->id = $objparent->fk_parent;
626  if (!$cat->containsObject($type, $obj->id)) {
627  $result = $cat->add_type($obj, $type);
628  if ($result < 0)
629  {
630  $this->error = $cat->error;
631  $error++;
632  }
633  }
634  }
635  }
636  }
637  else
638  {
639  $error++;
640  $this->error=$this->db->lasterror();
641  }
642 
643  if ($error)
644  {
645  $this->db->rollback();
646  return -1;
647  }
648  }
649 
650 
651 
652  // Call trigger
653  $this->context=array('linkto'=>$obj); // Save object we want to link category to into category instance to provide information to trigger
654  $result=$this->call_trigger('CATEGORY_LINK',$user);
655  if ($result < 0) { $error++; }
656  // End call triggers
657 
658  if (! $error)
659  {
660  $this->db->commit();
661  return 1;
662  }
663  else
664  {
665  $this->db->rollback();
666  return -2;
667  }
668  }
669  else
670  {
671  $this->db->rollback();
672  if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS')
673  {
674  $this->error=$this->db->lasterrno();
675  return -3;
676  }
677  else
678  {
679  $this->error=$this->db->lasterror();
680  }
681  return -1;
682  }
683  }
684 
685  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
694  function del_type($obj,$type)
695  {
696  // phpcs:enable
697  global $user,$langs,$conf;
698 
699  $error=0;
700 
701  // For backward compatibility
702  if ($type == 'societe') {
703  $type = 'customer';
704  dol_syslog( get_class( $this ) . "::del_type(): type 'societe' is deprecated, please use 'customer' instead", LOG_WARNING);
705  } elseif ($type == 'fournisseur') {
706  $type = 'supplier';
707  dol_syslog( get_class( $this ) . "::del_type(): type 'fournisseur' is deprecated, please use 'supplier' instead", LOG_WARNING);
708  }
709 
710  $this->db->begin();
711 
712  $sql = "DELETE FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type];
713  $sql .= " WHERE fk_categorie = " . $this->id;
714  $sql .= " AND fk_" . $this->MAP_CAT_FK[$type] . " = " . $obj->id;
715 
716  dol_syslog(get_class($this).'::del_type', LOG_DEBUG);
717  if ($this->db->query($sql))
718  {
719  // Call trigger
720  $this->context=array('unlinkoff'=>$obj); // Save object we want to link category to into category instance to provide information to trigger
721  $result=$this->call_trigger('CATEGORY_UNLINK',$user);
722  if ($result < 0) { $error++; }
723  // End call triggers
724 
725  if (! $error)
726  {
727  $this->db->commit();
728  return 1;
729  }
730  else
731  {
732  $this->db->rollback();
733  return -2;
734  }
735  }
736  else
737  {
738  $this->db->rollback();
739  $this->error=$this->db->lasterror();
740  return -1;
741  }
742  }
743 
752  function getObjectsInCateg($type, $onlyids=0)
753  {
754  $objs = array();
755 
756  $obj = new $this->MAP_OBJ_CLASS[$type]( $this->db );
757 
758  $sql = "SELECT c.fk_" . $this->MAP_CAT_FK[$type];
759  $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type] . " as c";
760  $sql .= ", " . MAIN_DB_PREFIX . $this->MAP_OBJ_TABLE[$type] . " as o";
761  $sql .= " WHERE o.entity IN (" . getEntity( $obj->element).")";
762  $sql.= " AND c.fk_categorie = ".$this->id;
763  $sql .= " AND c.fk_" . $this->MAP_CAT_FK[$type] . " = o.rowid";
764 
765  dol_syslog(get_class($this)."::getObjectsInCateg", LOG_DEBUG);
766  $resql = $this->db->query($sql);
767  if ($resql)
768  {
769  while ($rec = $this->db->fetch_array($resql))
770  {
771  if ($onlyids)
772  {
773  $objs[] = $rec['fk_' . $this->MAP_CAT_FK[$type]];
774  }
775  else
776  {
777  $obj = new $this->MAP_OBJ_CLASS[$type]( $this->db );
778  $obj->fetch( $rec['fk_' . $this->MAP_CAT_FK[$type]]);
779  $objs[] = $obj;
780  }
781  }
782  return $objs;
783  }
784  else
785  {
786  $this->error=$this->db->error().' sql='.$sql;
787  return -1;
788  }
789  }
790 
799  function containsObject($type, $object_id)
800  {
801  $sql = "SELECT COUNT(*) as nb FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type];
802  $sql .= " WHERE fk_categorie = " . $this->id . " AND fk_" . $this->MAP_CAT_FK[$type] . " = " . $object_id;
803  dol_syslog(get_class($this)."::containsObject", LOG_DEBUG);
804  $resql = $this->db->query($sql);
805  if ($resql) {
806  return $this->db->fetch_object($resql)->nb;
807  } else {
808  $this->error=$this->db->error().' sql='.$sql;
809  return -1;
810  }
811  }
812 
824  function getListForItem($id, $type='customer', $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
825  {
826  global $conf;
827 
828  $categories = array();
829 
830  $sub_type = $type;
831  $subcol_name = "fk_".$type;
832  if ($type=="customer") {
833  $sub_type="societe";
834  $subcol_name="fk_soc";
835  }
836  if ($type=="supplier") {
837  $sub_type="fournisseur";
838  $subcol_name="fk_soc";
839  }
840  if ($type=="contact") {
841  $subcol_name="fk_socpeople";
842  }
843  $sql = "SELECT s.rowid";
844  $sql.= " FROM ".MAIN_DB_PREFIX."categorie as s";
845  $sql.= " , ".MAIN_DB_PREFIX."categorie_".$sub_type." as sub ";
846  $sql.= ' WHERE s.entity IN ('.getEntity('category').')';
847  $sql.= ' AND s.type='.array_search($type, self::$MAP_ID_TO_CODE);
848  $sql.= ' AND s.rowid = sub.fk_categorie';
849  $sql.= ' AND sub.'.$subcol_name.' = '.$id;
850 
851  $sql.= $this->db->order($sortfield, $sortorder);
852 
853  $offset = 0;
854  $nbtotalofrecords = '';
855  if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
856  {
857  $result = $this->db->query($sql);
858  $nbtotalofrecords = $this->db->num_rows($result);
859  if (($page * $limit) > $nbtotalofrecords) // if total resultset is smaller then paging size (filtering), goto and load page 0
860  {
861  $page = 0;
862  $offset = 0;
863  }
864  }
865 
866  $sql.= $this->db->plimit($limit + 1, $offset);
867 
868  $result = $this->db->query($sql);
869  if ($result)
870  {
871  $i=0;
872  $num = $this->db->num_rows($result);
873  $min = min($num, ($limit <= 0 ? $num : $limit));
874  while ($i < $min)
875  {
876  $obj = $this->db->fetch_object($result);
877  $category_static = new Categorie($this->db);
878  if ($category_static->fetch($obj->rowid))
879  {
880  $categories[$i]['id'] = $category_static->id;
881  $categories[$i]['fk_parent'] = $category_static->fk_parent;
882  $categories[$i]['label'] = $category_static->label;
883  $categories[$i]['description'] = $category_static->description;
884  $categories[$i]['color'] = $category_static->color;
885  $categories[$i]['socid'] = $category_static->socid;
886  $categories[$i]['visible'] = $category_static->visible;
887  $categories[$i]['type'] = $category_static->type;
888  $categories[$i]['entity'] = $category_static->entity;
889  $categories[$i]['array_options'] = $category_static->array_options;
890 
891  // multilangs
892  if (! empty($conf->global->MAIN_MULTILANGS)) {
893  $categories[$i]['multilangs'] = $category_static->multilangs;
894  }
895  }
896  $i++;
897  }
898  }
899  else {
900  $this->error = $this->db->lasterror();
901  return -1;
902  }
903  if ( ! count($categories)) {
904  return 0;
905  }
906 
907  return $categories;
908  }
909 
910  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
916  function get_filles()
917  {
918  // phpcs:enable
919  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
920  $sql.= " WHERE fk_parent = ".$this->id;
921 
922  $res = $this->db->query($sql);
923  if ($res)
924  {
925  $cats = array ();
926  while ($rec = $this->db->fetch_array($res))
927  {
928  $cat = new Categorie($this->db);
929  $cat->fetch($rec['rowid']);
930  $cats[] = $cat;
931  }
932  return $cats;
933  }
934  else
935  {
936  dol_print_error($this->db);
937  return -1;
938  }
939  }
940 
941  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
947  private function load_motherof()
948  {
949  // phpcs:enable
950  global $conf;
951 
952  $this->motherof=array();
953 
954  // Load array[child]=parent
955  $sql = "SELECT fk_parent as id_parent, rowid as id_son";
956  $sql.= " FROM ".MAIN_DB_PREFIX."categorie";
957  $sql.= " WHERE fk_parent != 0";
958  $sql.= " AND entity IN (".getEntity('category').")";
959 
960  dol_syslog(get_class($this)."::load_motherof", LOG_DEBUG);
961  $resql = $this->db->query($sql);
962  if ($resql)
963  {
964  while ($obj= $this->db->fetch_object($resql))
965  {
966  $this->motherof[$obj->id_son]=$obj->id_parent;
967  }
968  return 1;
969  }
970  else
971  {
972  dol_print_error($this->db);
973  return -1;
974  }
975  }
976 
977  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
993  function get_full_arbo($type, $markafterid=0)
994  {
995  // phpcs:enable
996  global $conf, $langs;
997 
998  if (! is_numeric($type)) $type = $this->MAP_ID[$type];
999 
1000  $this->cats = array();
1001 
1002  // Init this->motherof that is array(id_son=>id_parent, ...)
1003  $this->load_motherof();
1004  $current_lang = $langs->getDefaultLang();
1005 
1006  // Init $this->cats array
1007  $sql = "SELECT DISTINCT c.rowid, c.label, c.description, c.color, c.fk_parent, c.visible"; // Distinct reduce pb with old tables with duplicates
1008  if (! empty($conf->global->MAIN_MULTILANGS)) $sql.= ", t.label as label_trans, t.description as description_trans";
1009  $sql.= " FROM ".MAIN_DB_PREFIX."categorie as c";
1010  if (! empty($conf->global->MAIN_MULTILANGS)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_lang as t ON t.fk_category=c.rowid AND t.lang='".$current_lang."'";
1011  $sql .= " WHERE c.entity IN (" . getEntity( 'category') . ")";
1012  $sql .= " AND c.type = " . $type;
1013 
1014  dol_syslog(get_class($this)."::get_full_arbo get category list", LOG_DEBUG);
1015  $resql = $this->db->query($sql);
1016  if ($resql)
1017  {
1018  $i=0;
1019  while ($obj = $this->db->fetch_object($resql))
1020  {
1021  $this->cats[$obj->rowid]['rowid'] = $obj->rowid;
1022  $this->cats[$obj->rowid]['id'] = $obj->rowid;
1023  $this->cats[$obj->rowid]['fk_parent'] = $obj->fk_parent;
1024  $this->cats[$obj->rowid]['label'] = ! empty($obj->label_trans) ? $obj->label_trans : $obj->label;
1025  $this->cats[$obj->rowid]['description'] = ! empty($obj->description_trans) ? $obj->description_trans : $obj->description;
1026  $this->cats[$obj->rowid]['color'] = $obj->color;
1027  $this->cats[$obj->rowid]['visible'] = $obj->visible;
1028  $i++;
1029  }
1030  }
1031  else
1032  {
1033  dol_print_error($this->db);
1034  return -1;
1035  }
1036 
1037  // We add the fullpath property to each elements of first level (no parent exists)
1038  dol_syslog(get_class($this)."::get_full_arbo call to build_path_from_id_categ", LOG_DEBUG);
1039  foreach($this->cats as $key => $val)
1040  {
1041  //print 'key='.$key.'<br>'."\n";
1042  $this->build_path_from_id_categ($key,0); // Process a branch from the root category key (this category has no parent)
1043  }
1044 
1045  // Exclude leaf including $markafterid from tree
1046  if ($markafterid)
1047  {
1048  //print "Look to discard category ".$markafterid."\n";
1049  $keyfilter1='^'.$markafterid.'$';
1050  $keyfilter2='_'.$markafterid.'$';
1051  $keyfilter3='^'.$markafterid.'_';
1052  $keyfilter4='_'.$markafterid.'_';
1053  foreach($this->cats as $key => $val)
1054  {
1055  if (preg_match('/'.$keyfilter1.'/',$val['fullpath']) || preg_match('/'.$keyfilter2.'/',$val['fullpath'])
1056  || preg_match('/'.$keyfilter3.'/',$val['fullpath']) || preg_match('/'.$keyfilter4.'/',$val['fullpath']))
1057  {
1058  unset($this->cats[$key]);
1059  }
1060  }
1061  }
1062 
1063  dol_syslog(get_class($this)."::get_full_arbo dol_sort_array", LOG_DEBUG);
1064  $this->cats=dol_sort_array($this->cats, 'fulllabel', 'asc', true, false);
1065 
1066  //$this->debug_cats();
1067 
1068  return $this->cats;
1069  }
1070 
1071  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1079  function build_path_from_id_categ($id_categ,$protection=1000)
1080  {
1081  // phpcs:enable
1082  dol_syslog(get_class($this)."::build_path_from_id_categ id_categ=".$id_categ." protection=".$protection, LOG_DEBUG);
1083 
1084  if (! empty($this->cats[$id_categ]['fullpath']))
1085  {
1086  // Already defined
1087  dol_syslog(get_class($this)."::build_path_from_id_categ fullpath and fulllabel already defined", LOG_WARNING);
1088  return;
1089  }
1090 
1091  // First build full array $motherof
1092  //$this->load_motherof(); // Disabled because already done by caller of build_path_from_id_categ
1093 
1094  // Define fullpath and fulllabel
1095  $this->cats[$id_categ]['fullpath'] = '_'.$id_categ;
1096  $this->cats[$id_categ]['fulllabel'] = $this->cats[$id_categ]['label'];
1097  $i=0; $cursor_categ=$id_categ;
1098  //print 'Work for id_categ='.$id_categ.'<br>'."\n";
1099  while ((empty($protection) || $i < $protection) && ! empty($this->motherof[$cursor_categ]))
1100  {
1101  //print '&nbsp; cursor_categ='.$cursor_categ.' i='.$i.' '.$this->motherof[$cursor_categ].'<br>'."\n";
1102  $this->cats[$id_categ]['fullpath'] = '_'.$this->motherof[$cursor_categ].$this->cats[$id_categ]['fullpath'];
1103  $this->cats[$id_categ]['fulllabel'] = $this->cats[$this->motherof[$cursor_categ]]['label'].' >> '.$this->cats[$id_categ]['fulllabel'];
1104  //print '&nbsp; Result for id_categ='.$id_categ.' : '.$this->cats[$id_categ]['fullpath'].' '.$this->cats[$id_categ]['fulllabel'].'<br>'."\n";
1105  $i++; $cursor_categ=$this->motherof[$cursor_categ];
1106  }
1107  //print 'Result for id_categ='.$id_categ.' : '.$this->cats[$id_categ]['fullpath'].'<br>'."\n";
1108 
1109  // We count number of _ to have level
1110  $this->cats[$id_categ]['level']=dol_strlen(preg_replace('/[^_]/i','',$this->cats[$id_categ]['fullpath']));
1111 
1112  return;
1113  }
1114 
1115  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1121  function debug_cats()
1122  {
1123  // phpcs:enable
1124  // Display $this->cats
1125  foreach($this->cats as $key => $val)
1126  {
1127  print 'id: '.$this->cats[$key]['id'];
1128  print ' label: '.$this->cats[$key]['label'];
1129  print ' mother: '.$this->cats[$key]['fk_parent'];
1130  //print ' children: '.(is_array($this->cats[$key]['id_children'])?join(',',$this->cats[$key]['id_children']):'');
1131  print ' fullpath: '.$this->cats[$key]['fullpath'];
1132  print ' fulllabel: '.$this->cats[$key]['fulllabel'];
1133  print "<br>\n";
1134  }
1135  }
1136 
1137 
1138  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1146  function get_all_categories($type=null, $parent=false)
1147  {
1148  // phpcs:enable
1149  if (! is_numeric($type)) $type = $this->MAP_ID[$type];
1150 
1151  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
1152  $sql.= " WHERE entity IN (".getEntity('category').")";
1153  if (! is_null($type))
1154  $sql.= " AND type = ".$type;
1155  if ($parent)
1156  $sql.= " AND fk_parent = 0";
1157 
1158  $res = $this->db->query($sql);
1159  if ($res)
1160  {
1161  $cats = array ();
1162  while ($rec = $this->db->fetch_array($res))
1163  {
1164  $cat = new Categorie($this->db);
1165  $cat->fetch($rec['rowid']);
1166  $cats[$rec['rowid']] = $cat;
1167  }
1168  return $cats;
1169  }
1170  else
1171  {
1172  dol_print_error($this->db);
1173  return -1;
1174  }
1175  }
1176 
1177  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1183  function already_exists()
1184  {
1185  // phpcs:enable
1186  $type=$this->type;
1187 
1188  if (! is_numeric($type)) $type=$this->MAP_ID[$type];
1189 
1190  /* We have to select any rowid from llx_categorie which category's mother and label
1191  * are equals to those of the calling category
1192  */
1193  $sql = "SELECT c.rowid";
1194  $sql.= " FROM ".MAIN_DB_PREFIX."categorie as c ";
1195  $sql.= " WHERE c.entity IN (".getEntity('category').")";
1196  $sql.= " AND c.type = ".$type;
1197  $sql.= " AND c.fk_parent = ".$this->fk_parent;
1198  $sql.= " AND c.label = '".$this->db->escape($this->label)."'";
1199 
1200  dol_syslog(get_class($this)."::already_exists", LOG_DEBUG);
1201  $resql = $this->db->query($sql);
1202  if ($resql)
1203  {
1204  if ($this->db->num_rows($resql) > 0) // Checking for empty resql
1205  {
1206  $obj = $this->db->fetch_array($resql);
1207  /* If object called create, obj cannot have is id.
1208  * If object called update, he mustn't have the same label as an other category for this mother.
1209  * So if the result have the same id, update is not for label, and if result have an other one,
1210  * update may be for label.
1211  */
1212  if($obj[0] > 0 && $obj[0] != $this->id)
1213  {
1214  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);
1215  return 1;
1216  }
1217  }
1218  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);
1219  return 0;
1220  }
1221  else
1222  {
1223  $this->error=$this->db->error();
1224  return -1;
1225  }
1226  }
1227 
1228  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1235  function get_main_categories($type=null)
1236  {
1237  // phpcs:enable
1238  return $this->get_all_categories($type, true);
1239  }
1240 
1241  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1251  function print_all_ways($sep = " &gt;&gt; ", $url='', $nocolor=0)
1252  {
1253  // phpcs:enable
1254  $ways = array();
1255 
1256  $allways = $this->get_all_ways(); // Load array of categories
1257  foreach ($allways as $way)
1258  {
1259  $w = array();
1260  $i = 0;
1261  $forced_color='';
1262  foreach ($way as $cat)
1263  {
1264  $i++;
1265 
1266  if (empty($nocolor))
1267  {
1268  $forced_color='toreplace';
1269  if ($i == count($way))
1270  {
1271  // Check contrast with background and correct text color
1272  $forced_color='categtextwhite';
1273  if ($cat->color)
1274  {
1275  if (colorIsLight($cat->color)) $forced_color='categtextblack';
1276  }
1277  }
1278  }
1279 
1280  if ($url == '')
1281  {
1282  $link = '<a href="'.DOL_URL_ROOT.'/categories/viewcat.php?id='.$cat->id.'&type='.$cat->type.'" class="'.$forced_color .'">';
1283  $linkend='</a>';
1284  $w[] = $link.$cat->label.$linkend;
1285  }
1286  else
1287  {
1288  $w[] = "<a href='".DOL_URL_ROOT."/$url?catid=".$cat->id."'>".$cat->label."</a>";
1289  }
1290  }
1291  $newcategwithpath = preg_replace('/toreplace/', $forced_color, implode($sep, $w));
1292 
1293  $ways[] = $newcategwithpath;
1294  }
1295 
1296  return $ways;
1297  }
1298 
1299 
1300  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1306  function get_meres()
1307  {
1308  // phpcs:enable
1309  $parents = array();
1310 
1311  $sql = "SELECT fk_parent FROM ".MAIN_DB_PREFIX."categorie";
1312  $sql.= " WHERE rowid = ".$this->id;
1313 
1314  $res = $this->db->query($sql);
1315 
1316  if ($res)
1317  {
1318  while ($rec = $this->db->fetch_array($res))
1319  {
1320  if ($rec['fk_parent'] > 0)
1321  {
1322  $cat = new Categorie($this->db);
1323  $cat->fetch($rec['fk_parent']);
1324  $parents[] = $cat;
1325  }
1326  }
1327  return $parents;
1328  }
1329  else
1330  {
1331  dol_print_error($this->db);
1332  return -1;
1333  }
1334  }
1335 
1336  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1343  function get_all_ways()
1344  {
1345  // phpcs:enable
1346  $ways = array();
1347 
1348  $parents=$this->get_meres();
1349  if (! empty($parents))
1350  {
1351  foreach ($parents as $parent)
1352  {
1353  $allways=$parent->get_all_ways();
1354  foreach ($allways as $way)
1355  {
1356  $w = $way;
1357  $w[] = $this;
1358  $ways[] = $w;
1359  }
1360  }
1361  }
1362 
1363  if (count($ways) == 0)
1364  $ways[0][0] = $this;
1365 
1366  return $ways;
1367  }
1368 
1379  function containing($id, $type, $mode='object')
1380  {
1381  $cats = array();
1382 
1383  if (is_numeric($type)) $type = Categorie::$MAP_ID_TO_CODE[$type];
1384 
1385  if ($type === Categorie::TYPE_BANK_LINE) // TODO Remove this with standard category code
1386  {
1387  // Load bank groups
1388  $sql = "SELECT c.label, c.rowid";
1389  $sql.= " FROM ".MAIN_DB_PREFIX."bank_class as a, ".MAIN_DB_PREFIX."bank_categ as c";
1390  $sql.= " WHERE a.lineid=".$id." AND a.fk_categ = c.rowid";
1391  $sql.= " ORDER BY c.label";
1392 
1393  $res = $this->db->query($sql);
1394  if ($res)
1395  {
1396  while ($obj = $this->db->fetch_object($res))
1397  {
1398  if ($mode == 'id') {
1399  $cats[] = $obj->rowid;
1400  } else if ($mode == 'label') {
1401  $cats[] = $obj->label;
1402  } else {
1403  $cat = new Categorie($this->db);
1404  $cat->id = $obj->rowid;
1405  $cat->label = $obj->label;
1406  $cats[] = $cat;
1407  }
1408  }
1409  }
1410  else
1411  {
1412  dol_print_error($this->db);
1413  return -1;
1414  }
1415  }
1416  else
1417  {
1418  $sql = "SELECT ct.fk_categorie, c.label, c.rowid";
1419  $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type] . " as ct, " . MAIN_DB_PREFIX . "categorie as c";
1420  $sql .= " WHERE ct.fk_categorie = c.rowid AND ct.fk_" . $this->MAP_CAT_FK[$type] . " = " . (int) $id . " AND c.type = " . $this->MAP_ID[$type];
1421  $sql .= " AND c.entity IN (" . getEntity( 'category') . ")";
1422 
1423  $res = $this->db->query($sql);
1424  if ($res)
1425  {
1426  while ($obj = $this->db->fetch_object($res))
1427  {
1428  if ($mode == 'id') {
1429  $cats[] = $obj->rowid;
1430  } else if ($mode == 'label') {
1431  $cats[] = $obj->label;
1432  } else {
1433  $cat = new Categorie($this->db);
1434  $cat->fetch($obj->fk_categorie);
1435  $cats[] = $cat;
1436  }
1437  }
1438  }
1439  else
1440  {
1441  dol_print_error($this->db);
1442  return -1;
1443  }
1444  }
1445 
1446  return $cats;
1447  }
1448 
1449 
1461  function rechercher($id, $nom, $type, $exact = false, $case = false)
1462  {
1463  // Deprecation warning
1464  if (is_numeric($type)) {
1465  dol_syslog(__METHOD__ . ': using numeric types is deprecated.', LOG_WARNING);
1466  }
1467 
1468  $cats = array();
1469 
1470  // For backward compatibility
1471  if (is_numeric($type)) {
1472  // We want to reverse lookup
1473  $map_type = array_flip( $this->MAP_ID );
1474  $type = $map_type[$type];
1475  dol_syslog( get_class( $this ) . "::rechercher(): numeric types are deprecated, please use string instead",
1476  LOG_WARNING );
1477  }
1478 
1479  // Generation requete recherche
1480  $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "categorie";
1481  $sql .= " WHERE type = " . $this->MAP_ID[$type];
1482  $sql .= " AND entity IN (" . getEntity( 'category') . ")";
1483  if ($nom)
1484  {
1485  if (! $exact)
1486  $nom = '%'.str_replace('*', '%', $nom).'%';
1487  if (! $case)
1488  $sql.= " AND label LIKE '".$this->db->escape($nom)."'";
1489  else
1490  $sql.= " AND label LIKE BINARY '".$this->db->escape($nom)."'";
1491  }
1492  if ($id)
1493  {
1494  $sql.=" AND rowid = '".$id."'";
1495  }
1496 
1497  $res = $this->db->query($sql);
1498  if ($res)
1499  {
1500  while ($rec = $this->db->fetch_array($res))
1501  {
1502  $cat = new Categorie($this->db);
1503  $cat->fetch($rec['rowid']);
1504  $cats[] = $cat;
1505  }
1506 
1507  return $cats;
1508  }
1509  else
1510  {
1511  $this->error=$this->db->error().' sql='.$sql;
1512  return -1;
1513  }
1514  }
1515 
1525  function getNomUrl($withpicto=0,$option='',$maxlength=0)
1526  {
1527  global $langs;
1528 
1529  $result='';
1530  $label=$langs->trans("ShowCategory").': '. ($this->ref?$this->ref:$this->label);
1531 
1532  // Check contrast with background and correct text color
1533  $forced_color='categtextwhite';
1534  if ($this->color)
1535  {
1536  if (colorIsLight($this->color)) $forced_color='categtextblack';
1537  }
1538 
1539  $link = '<a href="'.DOL_URL_ROOT.'/categories/viewcat.php?id='.$this->id.'&type='.$this->type.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip '.$forced_color .'">';
1540  $linkend='</a>';
1541 
1542  $picto='category';
1543 
1544 
1545  if ($withpicto) $result.=($link.img_object($label, $picto, 'class="classfortooltip"').$linkend);
1546  if ($withpicto && $withpicto != 2) $result.=' ';
1547  if ($withpicto != 2) $result.=$link.dol_trunc(($this->ref?$this->ref:$this->label),$maxlength).$linkend;
1548  return $result;
1549  }
1550 
1551 
1552  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1560  function add_photo($sdir, $file)
1561  {
1562  // phpcs:enable
1563  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1564 
1565  $dir = $sdir .'/'. get_exdir($this->id,2,0,0,$this,'category') . $this->id ."/";
1566  $dir .= "photos/";
1567 
1568  if (! file_exists($dir))
1569  {
1570  dol_mkdir($dir);
1571  }
1572 
1573  if (file_exists($dir)) {
1574  if (is_array($file['name']) && count($file['name']) > 0)
1575  {
1576  $nbfile = count($file['name']);
1577  for ($i = 0; $i <= $nbfile; $i ++) {
1578 
1579  $originImage = $dir . $file['name'][$i];
1580 
1581  // Cree fichier en taille origine
1582  dol_move_uploaded_file($file['tmp_name'][$i], $originImage, 1, 0, 0);
1583 
1584  if (file_exists($originImage)) {
1585  // Create thumbs
1586  $this->addThumbs($originImage);
1587  }
1588  }
1589  } else {
1590  $originImage = $dir . $file['name'];
1591 
1592  // Cree fichier en taille origine
1593  dol_move_uploaded_file($file['tmp_name'], $originImage, 1, 0, 0);
1594 
1595  if (file_exists($originImage)) {
1596  // Create thumbs
1597  $this->addThumbs($originImage);
1598  }
1599  }
1600  }
1601  }
1602 
1603  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1611  function liste_photos($dir,$nbmax=0)
1612  {
1613  // phpcs:enable
1614  include_once DOL_DOCUMENT_ROOT .'/core/lib/files.lib.php';
1615 
1616  $nbphoto=0;
1617  $tabobj=array();
1618 
1619  $dirthumb = $dir.'thumbs/';
1620 
1621  if (file_exists($dir))
1622  {
1623  $handle=opendir($dir);
1624  if (is_resource($handle))
1625  {
1626  while (($file = readdir($handle)) !== false)
1627  {
1628  if (dol_is_file($dir.$file) && preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$dir.$file))
1629  {
1630  $nbphoto++;
1631  $photo = $file;
1632 
1633  // On determine nom du fichier vignette
1634  $photo_vignette='';
1635  if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$photo,$regs))
1636  {
1637  $photo_vignette=preg_replace('/'.$regs[0].'/i','',$photo).'_small'.$regs[0];
1638  }
1639 
1640  // Objet
1641  $obj=array();
1642  $obj['photo']=$photo;
1643  if ($photo_vignette && is_file($dirthumb.$photo_vignette)) $obj['photo_vignette']='thumbs/' . $photo_vignette;
1644  else $obj['photo_vignette']="";
1645 
1646  $tabobj[$nbphoto-1]=$obj;
1647 
1648  // On continue ou on arrete de boucler
1649  if ($nbmax && $nbphoto >= $nbmax) break;
1650  }
1651  }
1652 
1653  closedir($handle);
1654  }
1655  }
1656 
1657  return $tabobj;
1658  }
1659 
1660  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1667  function delete_photo($file)
1668  {
1669  // phpcs:enable
1670  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1671 
1672  $dir = dirname($file).'/'; // Chemin du dossier contenant l'image d'origine
1673  $dirthumb = $dir.'/thumbs/'; // Chemin du dossier contenant la vignette
1674  $filename = preg_replace('/'.preg_quote($dir,'/').'/i','',$file); // Nom du fichier
1675 
1676  // On efface l'image d'origine
1677  dol_delete_file($file,1);
1678 
1679  // Si elle existe, on efface la vignette
1680  if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$filename,$regs))
1681  {
1682  $photo_vignette=preg_replace('/'.$regs[0].'/i','',$filename).'_small'.$regs[0];
1683  if (file_exists($dirthumb.$photo_vignette))
1684  {
1685  dol_delete_file($dirthumb.$photo_vignette,1);
1686  }
1687  }
1688  }
1689 
1690  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1697  function get_image_size($file)
1698  {
1699  // phpcs:enable
1700  $infoImg = getimagesize($file); // Recuperation des infos de l'image
1701  $this->imgWidth = $infoImg[0]; // Largeur de l'image
1702  $this->imgHeight = $infoImg[1]; // Hauteur de l'image
1703  }
1704 
1712  function setMultiLangs($user)
1713  {
1714  global $langs;
1715 
1716  $langs_available = $langs->get_available_languages();
1717  $current_lang = $langs->getDefaultLang();
1718 
1719  foreach ($langs_available as $key => $value)
1720  {
1721  $sql = "SELECT rowid";
1722  $sql.= " FROM ".MAIN_DB_PREFIX."categorie_lang";
1723  $sql.= " WHERE fk_category=".$this->id;
1724  $sql.= " AND lang='".$key."'";
1725 
1726  $result = $this->db->query($sql);
1727 
1728  if ($key == $current_lang)
1729  {
1730  if ($this->db->num_rows($result)) // si aucune ligne dans la base
1731  {
1732  $sql2 = "UPDATE ".MAIN_DB_PREFIX."categorie_lang";
1733  $sql2.= " SET label='".$this->db->escape($this->label)."',";
1734  $sql2.= " description='".$this->db->escape($this->description)."'";
1735  $sql2.= " WHERE fk_category=".$this->id." AND lang='".$this->db->escape($key)."'";
1736  }
1737  else
1738  {
1739  $sql2 = "INSERT INTO ".MAIN_DB_PREFIX."categorie_lang (fk_category, lang, label, description)";
1740  $sql2.= " VALUES(".$this->id.",'".$key."','". $this->db->escape($this->label);
1741  $sql2.= "','".$this->db->escape($this->multilangs["$key"]["description"])."')";
1742  }
1743  dol_syslog(get_class($this).'::setMultiLangs', LOG_DEBUG);
1744  if (! $this->db->query($sql2))
1745  {
1746  $this->error=$this->db->lasterror();
1747  return -1;
1748  }
1749  }
1750  else if (isset($this->multilangs["$key"]))
1751  {
1752  if ($this->db->num_rows($result)) // si aucune ligne dans la base
1753  {
1754  $sql2 = "UPDATE ".MAIN_DB_PREFIX."categorie_lang";
1755  $sql2.= " SET label='".$this->db->escape($this->multilangs["$key"]["label"])."',";
1756  $sql2.= " description='".$this->db->escape($this->multilangs["$key"]["description"])."'";
1757  $sql2.= " WHERE fk_category=".$this->id." AND lang='".$this->db->escape($key)."'";
1758  }
1759  else
1760  {
1761  $sql2 = "INSERT INTO ".MAIN_DB_PREFIX."categorie_lang (fk_category, lang, label, description)";
1762  $sql2.= " VALUES(".$this->id.",'".$key."','". $this->db->escape($this->multilangs["$key"]["label"]);
1763  $sql2.= "','".$this->db->escape($this->multilangs["$key"]["description"])."')";
1764  }
1765 
1766  // on ne sauvegarde pas des champs vides
1767  if ( $this->multilangs["$key"]["label"] || $this->multilangs["$key"]["description"] || $this->multilangs["$key"]["note"] )
1768  dol_syslog(get_class($this).'::setMultiLangs', LOG_DEBUG);
1769  if (! $this->db->query($sql2))
1770  {
1771  $this->error=$this->db->lasterror();
1772  return -1;
1773  }
1774  }
1775  }
1776 
1777  // Call trigger
1778  $result = $this->call_trigger('CATEGORY_SET_MULTILANGS',$user);
1779  if ($result < 0) {
1780  $this->error = $this->db->lasterror();
1781  return -1;
1782  }
1783  // End call triggers
1784 
1785  return 1;
1786  }
1787 
1793  function getMultiLangs()
1794  {
1795  global $langs;
1796 
1797  $current_lang = $langs->getDefaultLang();
1798 
1799  $sql = "SELECT lang, label, description";
1800  $sql.= " FROM ".MAIN_DB_PREFIX."categorie_lang";
1801  $sql.= " WHERE fk_category=".$this->id;
1802 
1803  $result = $this->db->query($sql);
1804  if ($result)
1805  {
1806  while ( $obj = $this->db->fetch_object($result) )
1807  {
1808  //print 'lang='.$obj->lang.' current='.$current_lang.'<br>';
1809  if( $obj->lang == $current_lang ) // si on a les traduct. dans la langue courante on les charge en infos principales.
1810  {
1811  $this->label = $obj->label;
1812  $this->description = $obj->description;
1813  }
1814  $this->multilangs["$obj->lang"]["label"] = $obj->label;
1815  $this->multilangs["$obj->lang"]["description"] = $obj->description;
1816  }
1817  return 1;
1818  }
1819  else
1820  {
1821  $this->error=$langs->trans("Error")." : ".$this->db->error()." - ".$sql;
1822  return -1;
1823  }
1824  }
1825 
1832  function getLibStatut($mode)
1833  {
1834  return '';
1835  }
1836 
1837 
1845  function initAsSpecimen()
1846  {
1847  dol_syslog(get_class($this)."::initAsSpecimen");
1848 
1849  // Initialise parametres
1850  $this->id=0;
1851  $this->fk_parent=0;
1852  $this->label = 'SPECIMEN';
1853  $this->specimen=1;
1854  $this->description = 'This is a description';
1855  $this->socid = 1;
1856  $this->type = self::TYPE_PRODUCT;
1857  }
1858 
1867  public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
1868  {
1869  $tables = array(
1870  'categorie_societe'
1871  );
1872 
1873  return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables, 1);
1874  }
1875 }
print $object label
hash of file content (md5_file(dol_osencode($destfull))
Definition: edit.php:153
getMultiLangs()
Load array this->multilangs.
static replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
print
Draft customers invoices.
Definition: index.php:91
dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $varfiles='addedfile')
Make control on an uploaded file from an GUI page and move it to final destination.
Definition: files.lib.php:996
if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) if(! empty($conf->don->enabled) && $user->rights->societe->lire) if(! empty($conf->tax->enabled) && $user->rights->tax->charges->lire) if(! empty($conf->facture->enabled) &&! empty($conf->commande->enabled) && $user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1053
addThumbs($file)
Build thumb Move this into files.lib.php.
create($user)
Add category into database.
</td >< td class="liste_titre" align="right"></td ></tr >< tr class="liste_titre">< input type="checkbox" onClick="toggle(this)"/> Ref p ref Label p label Duration p duration warehouseinternal SELECT description FROM product_lang WHERE qty< br > qty qty qty StockTooLow img yes disabled img no img no< tr class="oddeven">< td >< input type="checkbox" class="check" name="' . $i . '"' . $disabled . '></td >< td >< input type="checkbox" class="check" name="choose'.$i.'"></td >< td class="nowrap"></td >< td >< input type="hidden" name="desc' . $i . '" value="' . dol_escape_htmltag($objp-> description
Only used if Module[ID]Desc translation string is not found.
Definition: replenish.php:573
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...
debug_cats()
Display content of $this->cats.
get_filles()
Return childs of a category.
add_photo($sdir, $file)
Deplace fichier uploade sous le nom $files dans le repertoire sdir.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart)
Return a path to have a the directory according to object where files are stored. ...
setMultiLangs($user)
Update ou cree les traductions des infos produits.
print_all_ways($sep=" &gt;&gt; ", $url='', $nocolor=0)
Returns the path of the category, with the names of the categories separated by $sep (" >> " by defau...
update(User $user)
Update category.
Class to manage Dolibarr users.
Definition: user.class.php:41
Class to manage Dolibarr database access.
get_image_size($file)
Load size of image file.
delete_photo($file)
Efface la photo de la categorie et sa vignette.
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
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)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
get_all_categories($type=null, $parent=false)
Returns all categories.
getListForItem($id, $type='customer', $sortfield="s.rowid", $sortorder='ASC', $limit=0, $page=0)
List categories of an element id.
del_type($obj, $type)
Delete object from category.
containing($id, $type, $mode='object')
Return list of categories (object instances or labels) linked to element of id $id and type $type Sho...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
type
Definition: viewcat.php:284
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
Class to manage categories.
build_path_from_id_categ($id_categ, $protection=1000)
For category id_categ and its childs available in this->cats, define property fullpath and fulllabel...
get_main_categories($type=null)
Returns the top level categories (which are not girls)
containsObject($type, $object_id)
Check for the presence of an object in a category.
getObjectsInCateg($type, $onlyids=0)
Return list of fetched instance of elements having this category.
static commonReplaceThirdparty(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
fetch($id, $label='', $type=null)
Load category into memory from database.
getLibStatut($mode)
Return label of contact status.
__construct($db)
Constructor.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1)
Remove a file or several files with a mask.
Definition: files.lib.php:1139
deleteExtraFields()
Delete all extra fields values for the current object.
load_motherof()
Load this->motherof that is array(id_son=>id_parent, ...)
get_full_arbo($type, $markafterid=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.
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...
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:451
get_meres()
Returns an array containing the list of parent categories.
dol_mkdir($dir, $dataroot='', $newmask=null)
Creation of a directory (this can create recursive subdir)
liste_photos($dir, $nbmax=0)
Return tableau de toutes les photos de la categorie.
call_trigger($trigger_name, $user)
Call trigger based on this instance.
add_type($obj, $type)
Link an object to the category.
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 ...
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
initAsSpecimen()
Initialise an instance with random values.
Parent class of all other business classes (invoices, contracts, proposals, orders, ...)
getNomUrl($withpicto=0, $option='', $maxlength=0)
Return name and link of category (with picto) Use ->id, ->ref, ->label, ->color.