dolibarr  7.0.0-beta
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@capnetworks.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-2016 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  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program. If not, see <http://www.gnu.org/licenses/>.
26  */
27 
34 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
37 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
38 
39 
43 class Categorie extends CommonObject
44 {
45  // Categories types (we use string because we want to accept any modules/types in a future)
46  const TYPE_PRODUCT = 'product';
47  const TYPE_SUPPLIER = 'supplier';
48  const TYPE_CUSTOMER = 'customer';
49  const TYPE_MEMBER = 'member';
50  const TYPE_CONTACT = 'contact';
51  const TYPE_USER = 'user';
52  const TYPE_PROJECT = 'project';
53  const TYPE_ACCOUNT = 'bank_account';
54  const TYPE_BANK_LINE = 'bank_line';
55 
56  public $picto = 'category';
57 
58 
64  private $MAP_ID = array(
65  'product' => 0,
66  'supplier' => 1,
67  'customer' => 2,
68  'member' => 3,
69  'contact' => 4,
70  'bank_account' => 5,
71  'project' => 6,
72  'user' => 7,
73  'bank_line' => 8,
74  );
75  public static $MAP_ID_TO_CODE = array(
76  0 => 'product',
77  1 => 'supplier',
78  2 => 'customer',
79  3 => 'member',
80  4 => 'contact',
81  5 => 'bank_account',
82  6 => 'project',
83  7 => 'user',
84  8 => 'bank_line',
85  );
86 
92  private $MAP_CAT_FK = array(
93  'product' => 'product',
94  'customer' => 'soc',
95  'supplier' => 'soc',
96  'member' => 'member',
97  'contact' => 'socpeople',
98  'user' => 'user',
99  'account' => 'account', // old for bank_account
100  'bank_account' => 'account',
101  'project' => 'project',
102  );
108  private $MAP_CAT_TABLE = array(
109  'product' => 'product',
110  'customer' => 'societe',
111  'supplier' => 'fournisseur',
112  'member' => 'member',
113  'contact' => 'contact',
114  'user' => 'user',
115  'account' => 'account', // old for bank_account
116  'bank_account'=> 'account',
117  'project' => 'project',
118  );
124  private $MAP_OBJ_CLASS = array(
125  'product' => 'Product',
126  'customer' => 'Societe',
127  'supplier' => 'Fournisseur',
128  'member' => 'Adherent',
129  'contact' => 'Contact',
130  'user' => 'User',
131  'account' => 'Account', // old for bank account
132  'bank_account' => 'Account',
133  'project' => 'Project',
134  );
140  private $MAP_OBJ_TABLE = array(
141  'product' => 'product',
142  'customer' => 'societe',
143  'supplier' => 'societe',
144  'member' => 'adherent',
145  'contact' => 'socpeople',
146  'user' => 'user',
147  'account' => 'bank_account',
148  'project' => 'projet',
149  );
150 
151  public $element='category';
152  public $table_element='categorie';
153 
154  public $fk_parent;
155  public $label;
156  public $description;
160  public $color;
164  public $socid;
177  public $type;
178 
179  public $cats = array(); // Categories table in memory
180  public $motherof = array();
181 
187  function __construct($db)
188  {
189  $this->db = $db;
190  }
191 
200  function fetch($id, $label='', $type=null)
201  {
202  global $conf;
203 
204  // Check parameters
205  if (empty($id) && empty($label)) return -1;
206  if (! is_numeric($type)) $type=$this->MAP_ID[$type];
207 
208  $sql = "SELECT rowid, fk_parent, entity, label, description, color, fk_soc, visible, type";
209  $sql.= " FROM ".MAIN_DB_PREFIX."categorie";
210  if ($id > 0)
211  {
212  $sql.= " WHERE rowid = ".$id;
213  }
214  else
215  {
216  $sql.= " WHERE label = '".$this->db->escape($label)."' AND entity IN (".getEntity('category').")";
217  if (! is_null($type)) $sql.= " AND type = ".$this->db->escape($type);
218  }
219 
220  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
221  $resql = $this->db->query($sql);
222  if ($resql)
223  {
224  if ($this->db->num_rows($resql) > 0)
225  {
226  $res = $this->db->fetch_array($resql);
227 
228  $this->id = $res['rowid'];
229  //$this->ref = $res['rowid'];
230  $this->fk_parent = $res['fk_parent'];
231  $this->label = $res['label'];
232  $this->description = $res['description'];
233  $this->color = $res['color'];
234  $this->socid = $res['fk_soc'];
235  $this->visible = $res['visible'];
236  $this->type = $res['type'];
237  $this->entity = $res['entity'];
238 
239  $this->fetch_optionals($this->id,null);
240 
241  $this->db->free($resql);
242 
243  // multilangs
244  if (! empty($conf->global->MAIN_MULTILANGS)) $this->getMultiLangs();
245 
246  return 1;
247  }
248  else
249  {
250  return 0;
251  }
252  }
253  else
254  {
255  dol_print_error($this->db);
256  return -1;
257  }
258  }
259 
269  function create($user)
270  {
271  global $conf,$langs,$hookmanager;
272  $langs->load('categories');
273 
274  $type=$this->type;
275 
276  if (! is_numeric($type)) $type=$this->MAP_ID[$type];
277 
278  $error=0;
279 
280  dol_syslog(get_class($this).'::create', LOG_DEBUG);
281 
282  // Clean parameters
283  $this->label = trim($this->label);
284  $this->description = trim($this->description);
285  $this->color = trim($this->color);
286  $this->import_key = trim($this->import_key);
287  if (empty($this->visible)) $this->visible=0;
288  $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
289 
290  if ($this->already_exists())
291  {
292  $this->error=$langs->trans("ImpossibleAddCat", $this->label);
293  $this->error.=" : ".$langs->trans("CategoryExistsAtSameLevel");
294  dol_syslog($this->error, LOG_WARNING);
295  return -4;
296  }
297 
298  $this->db->begin();
299 
300  $sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie (";
301  $sql.= "fk_parent,";
302  $sql.= " label,";
303  $sql.= " description,";
304  $sql.= " color,";
305  if (! empty($conf->global->CATEGORY_ASSIGNED_TO_A_CUSTOMER))
306  {
307  $sql.= "fk_soc,";
308  }
309  $sql.= " visible,";
310  $sql.= " type,";
311  $sql.= " import_key,";
312  $sql.= " entity";
313  $sql.= ") VALUES (";
314  $sql.= $this->db->escape($this->fk_parent).",";
315  $sql.= "'".$this->db->escape($this->label)."',";
316  $sql.= "'".$this->db->escape($this->description)."',";
317  $sql.= "'".$this->db->escape($this->color)."',";
318  if (! empty($conf->global->CATEGORY_ASSIGNED_TO_A_CUSTOMER))
319  {
320  $sql.= ($this->socid != -1 ? $this->socid : 'null').",";
321  }
322  $sql.= "'".$this->db->escape($this->visible)."',";
323  $sql.= $this->db->escape($type).",";
324  $sql.= (! empty($this->import_key)?"'".$this->db->escape($this->import_key)."'":'null').",";
325  $sql.= $this->db->escape($conf->entity);
326  $sql.= ")";
327 
328  $res = $this->db->query($sql);
329  if ($res)
330  {
331  $id = $this->db->last_insert_id(MAIN_DB_PREFIX."categorie");
332 
333  if ($id > 0)
334  {
335  $this->id = $id;
336 
337  $action='create';
338 
339  // Actions on extra fields (by external module or standard code)
340  // TODO the hook duplicates the trigger !!
341  $hookmanager->initHooks(array('HookModuleNamedao'));
342  $parameters=array('socid'=>$this->id);
343  $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
344  if (empty($reshook))
345  {
346  if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
347  {
348  $result=$this->insertExtraFields();
349  if ($result < 0)
350  {
351  $error++;
352  }
353  }
354  }
355  else if ($reshook < 0) $error++;
356 
357  // Call trigger
358  $result=$this->call_trigger('CATEGORY_CREATE',$user);
359  if ($result < 0) { $error++; }
360  // End call triggers
361 
362  if ( ! $error )
363  {
364  $this->db->commit();
365  return $id;
366  }
367  else
368  {
369  $this->db->rollback();
370  return -3;
371  }
372  }
373  else
374  {
375  $this->db->rollback();
376  return -2;
377  }
378  }
379  else
380  {
381  $this->error=$this->db->error();
382  $this->db->rollback();
383  return -1;
384  }
385  }
386 
395  function update(User $user)
396  {
397  global $conf, $langs,$hookmanager;
398 
399  $error=0;
400 
401  // Clean parameters
402  $this->label=trim($this->label);
403  $this->description=trim($this->description);
404  $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
405  $this->visible = ($this->visible != "" ? intval($this->visible) : 0);
406 
407  if ($this->already_exists())
408  {
409  $this->error=$langs->trans("ImpossibleUpdateCat");
410  $this->error.=" : ".$langs->trans("CategoryExistsAtSameLevel");
411  return -1;
412  }
413 
414  $this->db->begin();
415 
416  $sql = "UPDATE ".MAIN_DB_PREFIX."categorie";
417  $sql.= " SET label = '".$this->db->escape($this->label)."',";
418  $sql.= " description = '".$this->db->escape($this->description)."',";
419  $sql.= " color = '".$this->db->escape($this->color)."'";
420  if (! empty($conf->global->CATEGORY_ASSIGNED_TO_A_CUSTOMER))
421  {
422  $sql .= ", fk_soc = ".($this->socid != -1 ? $this->socid : 'null');
423  }
424  $sql .= ", visible = '".$this->db->escape($this->visible)."'";
425  $sql .= ", fk_parent = ".$this->fk_parent;
426  $sql .= " WHERE rowid = ".$this->id;
427 
428  dol_syslog(get_class($this)."::update", LOG_DEBUG);
429  if ($this->db->query($sql))
430  {
431  $action='update';
432 
433  // Actions on extra fields (by external module or standard code)
434  // TODO the hook duplicates the trigger !!
435  $hookmanager->initHooks(array('HookCategorydao'));
436  $parameters=array();
437  $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
438  if (empty($reshook))
439  {
440  if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
441  {
442  $result=$this->insertExtraFields();
443  if ($result < 0)
444  {
445  $error++;
446  }
447  }
448  }
449  else if ($reshook < 0) $error++;
450 
451  // Call trigger
452  $result=$this->call_trigger('CATEGORY_MODIFY',$user);
453  if ($result < 0) { $error++; $this->db->rollback(); return -1; }
454  // End call triggers
455 
456  $this->db->commit();
457 
458  return 1;
459  }
460  else
461  {
462  $this->db->rollback();
463  dol_print_error($this->db);
464  return -1;
465  }
466  }
467 
475  function delete($user, $notrigger=0)
476  {
477  global $conf,$langs;
478 
479  $error=0;
480 
481  // Clean parameters
482  $this->fk_parent = ($this->fk_parent != "" ? intval($this->fk_parent) : 0);
483 
484  dol_syslog(get_class($this)."::remove");
485 
486  $this->db->begin();
487 
488  if (! $error && ! $notrigger)
489  {
490  // Call trigger
491  $result=$this->call_trigger('CATEGORY_DELETE',$user);
492  if ($result < 0) $error++;
493  // End call triggers
494  }
495 
496  /* FIX #1317 : Check for child category and move up 1 level*/
497  if (! $error)
498  {
499  $sql = "UPDATE ".MAIN_DB_PREFIX."categorie";
500  $sql.= " SET fk_parent = ".$this->fk_parent;
501  $sql.= " WHERE fk_parent = ".$this->id;
502 
503  if (!$this->db->query($sql))
504  {
505  $this->error=$this->db->lasterror();
506  $error++;
507  }
508  }
509  if (! $error)
510  {
511  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_societe";
512  $sql .= " WHERE fk_categorie = ".$this->id;
513  if (!$this->db->query($sql))
514  {
515  $this->error=$this->db->lasterror();
516  $error++;
517  }
518  }
519  if (! $error)
520  {
521  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_fournisseur";
522  $sql .= " WHERE fk_categorie = ".$this->id;
523  if (!$this->db->query($sql))
524  {
525  $this->error=$this->db->lasterror();
526  $error++;
527  }
528  }
529  if (! $error)
530  {
531  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_product";
532  $sql .= " WHERE fk_categorie = ".$this->id;
533  if (!$this->db->query($sql))
534  {
535  $this->error=$this->db->lasterror();
536  $error++;
537  }
538  }
539  if (! $error)
540  {
541  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member";
542  $sql .= " WHERE fk_categorie = ".$this->id;
543  if (!$this->db->query($sql))
544  {
545  $this->error=$this->db->lasterror();
546  $error++;
547  }
548  }
549  if (! $error)
550  {
551  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_contact";
552  $sql .= " WHERE fk_categorie = ".$this->id;
553  if (!$this->db->query($sql))
554  {
555  $this->error=$this->db->lasterror();
556  $error++;
557  }
558  }
559  if (! $error)
560  {
561  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_contact";
562  $sql .= " WHERE fk_categorie = ".$this->id;
563  if (!$this->db->query($sql))
564  {
565  $this->error=$this->db->lasterror();
566  $error++;
567  }
568  }
569  if (! $error)
570  {
571  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
572  $sql .= " WHERE fk_categorie = ".$this->id;
573  if (!$this->db->query($sql))
574  {
575  $this->error=$this->db->lasterror();
576  dol_syslog("Error sql=".$sql." ".$this->error, LOG_ERR);
577  $error++;
578  }
579  }
580  if (! $error)
581  {
582  $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_class";
583  $sql .= " WHERE fk_categ = ".$this->id;
584  if (!$this->db->query($sql))
585  {
586  $this->error=$this->db->lasterror();
587  dol_syslog("Error sql=".$sql." ".$this->error, LOG_ERR);
588  $error++;
589  }
590  }
591 
592  if (! $error)
593  {
594  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_lang";
595  $sql .= " WHERE fk_category = ".$this->id;
596  if (!$this->db->query($sql))
597  {
598  $this->error=$this->db->lasterror();
599  dol_syslog("Error sql=".$sql." ".$this->error, LOG_ERR);
600  $error++;
601  }
602  }
603 
604  // Delete category
605  if (! $error)
606  {
607  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie";
608  $sql .= " WHERE rowid = ".$this->id;
609  if (!$this->db->query($sql))
610  {
611  $this->error=$this->db->lasterror();
612  $error++;
613  }
614  }
615 
616  // Removed extrafields
617  if (! $error && empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
618  {
619  $result=$this->deleteExtraFields();
620  if ($result < 0)
621  {
622  $error++;
623  dol_syslog(get_class($this)."::delete erreur ".$this->error, LOG_ERR);
624  }
625  }
626 
627  if (! $error)
628  {
629  $this->db->commit();
630  return 1;
631  }
632  else
633  {
634  $this->db->rollback();
635  return -1;
636  }
637  }
638 
646  function add_type($obj, $type)
647  {
648  global $user,$langs,$conf;
649 
650  $error=0;
651 
652  if ($this->id == -1) return -2;
653 
654  // For backward compatibility
655  if ($type == 'societe')
656  {
657  $type = 'customer';
658  dol_syslog(get_class($this) . "::add_type(): type 'societe' is deprecated, please use 'customer' instead", LOG_WARNING);
659  }
660  elseif ($type == 'fournisseur')
661  {
662  $type = 'supplier';
663  dol_syslog(get_class($this) . "::add_type(): type 'fournisseur' is deprecated, please use 'supplier' instead", LOG_WARNING);
664  }
665 
666  $this->db->begin();
667 
668  $sql = "INSERT INTO " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type];
669  $sql .= " (fk_categorie, fk_" . $this->MAP_CAT_FK[$type] . ")";
670  $sql .= " VALUES (" . $this->id . ", " . $obj->id . ")";
671 
672  dol_syslog(get_class($this).'::add_type', LOG_DEBUG);
673  if ($this->db->query($sql))
674  {
675  if (! empty($conf->global->CATEGORIE_RECURSIV_ADD))
676  {
677  $sql = 'SELECT fk_parent FROM '.MAIN_DB_PREFIX.'categorie';
678  $sql.= " WHERE rowid = ".$this->id;
679 
680  dol_syslog(get_class($this)."::add_type", LOG_DEBUG);
681  $resql=$this->db->query($sql);
682  if ($resql)
683  {
684  if ($this->db->num_rows($resql) > 0)
685  {
686  $objparent = $this->db->fetch_object($resql);
687 
688  if (!empty($objparent->fk_parent))
689  {
690  $cat = new Categorie($this->db);
691  $cat->id = $objparent->fk_parent;
692  if (!$cat->containsObject($type, $obj->id)) {
693  $result = $cat->add_type($obj, $type);
694  if ($result < 0)
695  {
696  $this->error = $cat->error;
697  $error++;
698  }
699  }
700  }
701  }
702  }
703  else
704  {
705  $error++;
706  $this->error=$this->db->lasterror();
707  }
708 
709  if ($error)
710  {
711  $this->db->rollback();
712  return -1;
713  }
714  }
715 
716  // Save object we want to link category to into category instance to provide information to trigger
717  $this->linkto=$obj;
718 
719  // Call trigger
720  $result=$this->call_trigger('CATEGORY_LINK',$user);
721  if ($result < 0) { $error++; }
722  // End call triggers
723 
724  if (! $error)
725  {
726  $this->db->commit();
727  return 1;
728  }
729  else
730  {
731  $this->db->rollback();
732  return -2;
733  }
734 
735  }
736  else
737  {
738  $this->db->rollback();
739  if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS')
740  {
741  $this->error=$this->db->lasterrno();
742  return -3;
743  }
744  else
745  {
746  $this->error=$this->db->lasterror();
747  }
748  return -1;
749  }
750  }
751 
760  function del_type($obj,$type)
761  {
762  global $user,$langs,$conf;
763 
764  $error=0;
765 
766  // For backward compatibility
767  if ($type == 'societe') {
768  $type = 'customer';
769  dol_syslog( get_class( $this ) . "::del_type(): type 'societe' is deprecated, please use 'customer' instead", LOG_WARNING);
770  } elseif ($type == 'fournisseur') {
771  $type = 'supplier';
772  dol_syslog( get_class( $this ) . "::del_type(): type 'fournisseur' is deprecated, please use 'supplier' instead", LOG_WARNING);
773  }
774 
775  $this->db->begin();
776 
777  $sql = "DELETE FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type];
778  $sql .= " WHERE fk_categorie = " . $this->id;
779  $sql .= " AND fk_" . $this->MAP_CAT_FK[$type] . " = " . $obj->id;
780 
781  dol_syslog(get_class($this).'::del_type', LOG_DEBUG);
782  if ($this->db->query($sql))
783  {
784  // Save object we want to unlink category off into category instance to provide information to trigger
785  $this->unlinkoff=$obj;
786 
787  // Call trigger
788  $result=$this->call_trigger('CATEGORY_UNLINK',$user);
789  if ($result < 0) { $error++; }
790  // End call triggers
791 
792  if (! $error)
793  {
794  $this->db->commit();
795  return 1;
796  }
797  else
798  {
799  $this->db->rollback();
800  return -2;
801  }
802  }
803  else
804  {
805  $this->db->rollback();
806  $this->error=$this->db->lasterror();
807  return -1;
808  }
809  }
810 
819  function getObjectsInCateg($type, $onlyids=0)
820  {
821  $objs = array();
822 
823  $obj = new $this->MAP_OBJ_CLASS[$type]( $this->db );
824 
825  $sql = "SELECT c.fk_" . $this->MAP_CAT_FK[$type];
826  $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type] . " as c";
827  $sql .= ", " . MAIN_DB_PREFIX . $this->MAP_OBJ_TABLE[$type] . " as o";
828  $sql .= " WHERE o.entity IN (" . getEntity( $obj->element, 1).")";
829  $sql.= " AND c.fk_categorie = ".$this->id;
830  $sql .= " AND c.fk_" . $this->MAP_CAT_FK[$type] . " = o.rowid";
831 
832  dol_syslog(get_class($this)."::getObjectsInCateg", LOG_DEBUG);
833  $resql = $this->db->query($sql);
834  if ($resql)
835  {
836  while ($rec = $this->db->fetch_array($resql))
837  {
838  if ($onlyids)
839  {
840  $objs[] = $rec['fk_' . $this->MAP_CAT_FK[$type]];
841  }
842  else
843  {
844  $obj = new $this->MAP_OBJ_CLASS[$type]( $this->db );
845  $obj->fetch( $rec['fk_' . $this->MAP_CAT_FK[$type]]);
846  $objs[] = $obj;
847  }
848  }
849  return $objs;
850  }
851  else
852  {
853  $this->error=$this->db->error().' sql='.$sql;
854  return -1;
855  }
856  }
857 
866  function containsObject($type, $object_id)
867  {
868  $sql = "SELECT COUNT(*) as nb FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type];
869  $sql .= " WHERE fk_categorie = " . $this->id . " AND fk_" . $this->MAP_CAT_FK[$type] . " = " . $object_id;
870  dol_syslog(get_class($this)."::containsObject", LOG_DEBUG);
871  $resql = $this->db->query($sql);
872  if ($resql) {
873  return $this->db->fetch_object($resql)->nb;
874  } else {
875  $this->error=$this->db->error().' sql='.$sql;
876  return -1;
877  }
878  }
879 
891  function getListForItem($id, $type='customer', $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
892  {
893  global $conf;
894 
895  $categories = array();
896 
897  $sub_type = $type;
898  $subcol_name = "fk_".$type;
899  if ($type=="customer" || $type=="supplier") {
900  $sub_type="societe";
901  $subcol_name="fk_soc";
902  }
903  if ($type=="contact") {
904  $subcol_name="fk_socpeople";
905  }
906  $sql = "SELECT s.rowid";
907  $sql.= " FROM ".MAIN_DB_PREFIX."categorie as s";
908  $sql.= " , ".MAIN_DB_PREFIX."categorie_".$sub_type." as sub ";
909  $sql.= ' WHERE s.entity IN ('.getEntity('category').')';
910  $sql.= ' AND s.type='.array_search($type, self::$MAP_ID_TO_CODE);
911  $sql.= ' AND s.rowid = sub.fk_categorie';
912  $sql.= ' AND sub.'.$subcol_name.' = '.$id;
913 
914  $nbtotalofrecords = '';
915  if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
916  {
917  $result = $this->db->query($sql);
918  $nbtotalofrecords = $this->db->num_rows($result);
919  }
920 
921  $sql.= $this->db->order($sortfield, $sortorder);
922  if ($limit) {
923  if ($page < 0)
924  {
925  $page = 0;
926  }
927  $offset = $limit * $page;
928 
929  $sql.= $this->db->plimit($limit + 1, $offset);
930  }
931 
932  $result = $this->db->query($sql);
933  if ($result)
934  {
935  $i=0;
936  $num = $this->db->num_rows($result);
937  $min = min($num, ($limit <= 0 ? $num : $limit));
938  while ($i < $min)
939  {
940  $obj = $this->db->fetch_object($result);
941  $category_static = new Categorie($this->db);
942  if ($category_static->fetch($obj->rowid))
943  {
944  $categories[$i]['id'] = $category_static->id;
945  $categories[$i]['fk_parent'] = $category_static->fk_parent;
946  $categories[$i]['label'] = $category_static->label;
947  $categories[$i]['description'] = $category_static->description;
948  $categories[$i]['color'] = $category_static->color;
949  $categories[$i]['socid'] = $category_static->socid;
950  $categories[$i]['visible'] = $category_static->visible;
951  $categories[$i]['type'] = $category_static->type;
952  $categories[$i]['entity'] = $category_static->entity;
953  $categories[$i]['array_options'] = $category_static->array_options;
954 
955  // multilangs
956  if (! empty($conf->global->MAIN_MULTILANGS)) {
957  $categories[$i]['multilangs'] = $category_static->multilangs;
958  }
959  }
960  $i++;
961  }
962  }
963  else {
964  $this->error = $this->db->lasterror();
965  return -1;
966  }
967  if ( ! count($categories)) {
968  return 0;
969  }
970 
971  return $categories;
972  }
973 
979  function get_filles()
980  {
981  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
982  $sql.= " WHERE fk_parent = ".$this->id;
983 
984  $res = $this->db->query($sql);
985  if ($res)
986  {
987  $cats = array ();
988  while ($rec = $this->db->fetch_array($res))
989  {
990  $cat = new Categorie($this->db);
991  $cat->fetch($rec['rowid']);
992  $cats[] = $cat;
993  }
994  return $cats;
995  }
996  else
997  {
998  dol_print_error($this->db);
999  return -1;
1000  }
1001  }
1002 
1008  private function load_motherof()
1009  {
1010  global $conf;
1011 
1012  $this->motherof=array();
1013 
1014  // Load array[child]=parent
1015  $sql = "SELECT fk_parent as id_parent, rowid as id_son";
1016  $sql.= " FROM ".MAIN_DB_PREFIX."categorie";
1017  $sql.= " WHERE fk_parent != 0";
1018  $sql.= " AND entity IN (".getEntity('category').")";
1019 
1020  dol_syslog(get_class($this)."::load_motherof", LOG_DEBUG);
1021  $resql = $this->db->query($sql);
1022  if ($resql)
1023  {
1024  while ($obj= $this->db->fetch_object($resql))
1025  {
1026  $this->motherof[$obj->id_son]=$obj->id_parent;
1027  }
1028  return 1;
1029  }
1030  else
1031  {
1032  dol_print_error($this->db);
1033  return -1;
1034  }
1035  }
1036 
1052  function get_full_arbo($type, $markafterid=0)
1053  {
1054  global $conf, $langs;
1055 
1056  if (! is_numeric($type)) $type = $this->MAP_ID[$type];
1057 
1058  $this->cats = array();
1059 
1060  // Init this->motherof that is array(id_son=>id_parent, ...)
1061  $this->load_motherof();
1062  $current_lang = $langs->getDefaultLang();
1063 
1064  // Init $this->cats array
1065  $sql = "SELECT DISTINCT c.rowid, c.label, c.description, c.color, c.fk_parent"; // Distinct reduce pb with old tables with duplicates
1066  if (! empty($conf->global->MAIN_MULTILANGS)) $sql.= ", t.label as label_trans, t.description as description_trans";
1067  $sql.= " FROM ".MAIN_DB_PREFIX."categorie as c";
1068  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."'";
1069  $sql .= " WHERE c.entity IN (" . getEntity( 'category', 1 ) . ")";
1070  $sql .= " AND c.type = " . $type;
1071 
1072  dol_syslog(get_class($this)."::get_full_arbo get category list", LOG_DEBUG);
1073  $resql = $this->db->query($sql);
1074  if ($resql)
1075  {
1076  $i=0;
1077  while ($obj = $this->db->fetch_object($resql))
1078  {
1079  $this->cats[$obj->rowid]['rowid'] = $obj->rowid;
1080  $this->cats[$obj->rowid]['id'] = $obj->rowid;
1081  $this->cats[$obj->rowid]['fk_parent'] = $obj->fk_parent;
1082  $this->cats[$obj->rowid]['label'] = ! empty($obj->label_trans) ? $obj->label_trans : $obj->label;
1083  $this->cats[$obj->rowid]['description'] = ! empty($obj->description_trans) ? $obj->description_trans : $obj->description;
1084  $this->cats[$obj->rowid]['color'] = $obj->color;
1085  $i++;
1086  }
1087  }
1088  else
1089  {
1090  dol_print_error($this->db);
1091  return -1;
1092  }
1093 
1094  // We add the fullpath property to each elements of first level (no parent exists)
1095  dol_syslog(get_class($this)."::get_full_arbo call to build_path_from_id_categ", LOG_DEBUG);
1096  foreach($this->cats as $key => $val)
1097  {
1098  //print 'key='.$key.'<br>'."\n";
1099  $this->build_path_from_id_categ($key,0); // Process a branch from the root category key (this category has no parent)
1100  }
1101 
1102  // Exclude leaf including $markafterid from tree
1103  if ($markafterid)
1104  {
1105  //print "Look to discard category ".$markafterid."\n";
1106  $keyfilter1='^'.$markafterid.'$';
1107  $keyfilter2='_'.$markafterid.'$';
1108  $keyfilter3='^'.$markafterid.'_';
1109  $keyfilter4='_'.$markafterid.'_';
1110  foreach($this->cats as $key => $val)
1111  {
1112  if (preg_match('/'.$keyfilter1.'/',$val['fullpath']) || preg_match('/'.$keyfilter2.'/',$val['fullpath'])
1113  || preg_match('/'.$keyfilter3.'/',$val['fullpath']) || preg_match('/'.$keyfilter4.'/',$val['fullpath']))
1114  {
1115  unset($this->cats[$key]);
1116  }
1117  }
1118  }
1119 
1120  dol_syslog(get_class($this)."::get_full_arbo dol_sort_array", LOG_DEBUG);
1121  $this->cats=dol_sort_array($this->cats, 'fulllabel', 'asc', true, false);
1122 
1123  //$this->debug_cats();
1124 
1125  return $this->cats;
1126  }
1127 
1135  function build_path_from_id_categ($id_categ,$protection=1000)
1136  {
1137  dol_syslog(get_class($this)."::build_path_from_id_categ id_categ=".$id_categ." protection=".$protection, LOG_DEBUG);
1138 
1139  if (! empty($this->cats[$id_categ]['fullpath']))
1140  {
1141  // Already defined
1142  dol_syslog(get_class($this)."::build_path_from_id_categ fullpath and fulllabel already defined", LOG_WARNING);
1143  return;
1144  }
1145 
1146  // First build full array $motherof
1147  //$this->load_motherof(); // Disabled because already done by caller of build_path_from_id_categ
1148 
1149  // Define fullpath and fulllabel
1150  $this->cats[$id_categ]['fullpath'] = '_'.$id_categ;
1151  $this->cats[$id_categ]['fulllabel'] = $this->cats[$id_categ]['label'];
1152  $i=0; $cursor_categ=$id_categ;
1153  //print 'Work for id_categ='.$id_categ.'<br>'."\n";
1154  while ((empty($protection) || $i < $protection) && ! empty($this->motherof[$cursor_categ]))
1155  {
1156  //print '&nbsp; cursor_categ='.$cursor_categ.' i='.$i.' '.$this->motherof[$cursor_categ].'<br>'."\n";
1157  $this->cats[$id_categ]['fullpath'] = '_'.$this->motherof[$cursor_categ].$this->cats[$id_categ]['fullpath'];
1158  $this->cats[$id_categ]['fulllabel'] = $this->cats[$this->motherof[$cursor_categ]]['label'].' >> '.$this->cats[$id_categ]['fulllabel'];
1159  //print '&nbsp; Result for id_categ='.$id_categ.' : '.$this->cats[$id_categ]['fullpath'].' '.$this->cats[$id_categ]['fulllabel'].'<br>'."\n";
1160  $i++; $cursor_categ=$this->motherof[$cursor_categ];
1161  }
1162  //print 'Result for id_categ='.$id_categ.' : '.$this->cats[$id_categ]['fullpath'].'<br>'."\n";
1163 
1164  // We count number of _ to have level
1165  $this->cats[$id_categ]['level']=dol_strlen(preg_replace('/[^_]/i','',$this->cats[$id_categ]['fullpath']));
1166 
1167  return;
1168  }
1169 
1175  function debug_cats()
1176  {
1177  // Display $this->cats
1178  foreach($this->cats as $key => $val)
1179  {
1180  print 'id: '.$this->cats[$key]['id'];
1181  print ' label: '.$this->cats[$key]['label'];
1182  print ' mother: '.$this->cats[$key]['fk_parent'];
1183  //print ' children: '.(is_array($this->cats[$key]['id_children'])?join(',',$this->cats[$key]['id_children']):'');
1184  print ' fullpath: '.$this->cats[$key]['fullpath'];
1185  print ' fulllabel: '.$this->cats[$key]['fulllabel'];
1186  print "<br>\n";
1187  }
1188  }
1189 
1190 
1198  function get_all_categories($type=null, $parent=false)
1199  {
1200  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
1201  $sql.= " WHERE entity IN (".getEntity('category').")";
1202  if (! is_null($type))
1203  $sql.= " AND type = ".$type;
1204  if ($parent)
1205  $sql.= " AND fk_parent = 0";
1206 
1207  $res = $this->db->query($sql);
1208  if ($res)
1209  {
1210  $cats = array ();
1211  while ($rec = $this->db->fetch_array($res))
1212  {
1213  $cat = new Categorie($this->db);
1214  $cat->fetch($rec['rowid']);
1215  $cats[$rec['rowid']] = $cat;
1216  }
1217  return $cats;
1218  }
1219  else
1220  {
1221  dol_print_error($this->db);
1222  return -1;
1223  }
1224  }
1225 
1233  {
1234  $sql = "SELECT count(rowid)";
1235  $sql.= " FROM ".MAIN_DB_PREFIX."categorie";
1236  $sql.= " WHERE entity IN (".getEntity('category').")";
1237  $res = $this->db->query($sql);
1238  if ($res)
1239  {
1240  $res = $this->db->fetch_array($res);
1241  return $res[0];
1242  }
1243  else
1244  {
1245  dol_print_error($this->db);
1246  return -1;
1247  }
1248  }
1249 
1255  function already_exists()
1256  {
1257  $type=$this->type;
1258 
1259  if (! is_numeric($type)) $type=$this->MAP_ID[$type];
1260 
1261  /* We have to select any rowid from llx_categorie which category's mother and label
1262  * are equals to those of the calling category
1263  */
1264  $sql = "SELECT c.rowid";
1265  $sql.= " FROM ".MAIN_DB_PREFIX."categorie as c ";
1266  $sql.= " WHERE c.entity IN (".getEntity('category').")";
1267  $sql.= " AND c.type = ".$type;
1268  $sql.= " AND c.fk_parent = ".$this->fk_parent;
1269  $sql.= " AND c.label = '".$this->db->escape($this->label)."'";
1270 
1271  dol_syslog(get_class($this)."::already_exists", LOG_DEBUG);
1272  $resql = $this->db->query($sql);
1273  if ($resql)
1274  {
1275  if ($this->db->num_rows($resql) > 0) // Checking for empty resql
1276  {
1277  $obj = $this->db->fetch_array($resql);
1278  /* If object called create, obj cannot have is id.
1279  * If object called update, he mustn't have the same label as an other category for this mother.
1280  * So if the result have the same id, update is not for label, and if result have an other one,
1281  * update may be for label.
1282  */
1283  if($obj[0] > 0 && $obj[0] != $this->id)
1284  {
1285  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);
1286  return 1;
1287  }
1288  }
1289  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);
1290  return 0;
1291  }
1292  else
1293  {
1294  $this->error=$this->db->error();
1295  return -1;
1296  }
1297  }
1298 
1305  function get_main_categories($type=null)
1306  {
1307  return $this->get_all_categories($type, true);
1308  }
1309 
1319  function print_all_ways($sep = " &gt;&gt; ", $url='', $nocolor=0)
1320  {
1321  $ways = array();
1322 
1323  $allways = $this->get_all_ways(); // Load array of categories
1324  foreach ($allways as $way)
1325  {
1326  $w = array();
1327  $i = 0;
1328  $forced_color='';
1329  foreach ($way as $cat)
1330  {
1331  $i++;
1332 
1333  if (empty($nocolor))
1334  {
1335  $forced_color='toreplace';
1336  if ($i == count($way))
1337  {
1338  // Check contrast with background and correct text color
1339  $forced_color='categtextwhite';
1340  if ($cat->color)
1341  {
1342  if (colorIsLight($cat->color)) $forced_color='categtextblack';
1343  }
1344  }
1345  }
1346 
1347  if ($url == '')
1348  {
1349  $link = '<a href="'.DOL_URL_ROOT.'/categories/viewcat.php?id='.$cat->id.'&type='.$cat->type.'" class="'.$forced_color .'">';
1350  $linkend='</a>';
1351  $w[] = $link.$cat->label.$linkend;
1352  }
1353  else
1354  {
1355  $w[] = "<a href='".DOL_URL_ROOT."/$url?catid=".$cat->id."'>".$cat->label."</a>";
1356  }
1357  }
1358  $newcategwithpath = preg_replace('/toreplace/', $forced_color, implode($sep, $w));
1359 
1360  $ways[] = $newcategwithpath;
1361  }
1362 
1363  return $ways;
1364  }
1365 
1366 
1372  function get_meres()
1373  {
1374  $parents = array();
1375 
1376  $sql = "SELECT fk_parent FROM ".MAIN_DB_PREFIX."categorie";
1377  $sql.= " WHERE rowid = ".$this->id;
1378 
1379  $res = $this->db->query($sql);
1380 
1381  if ($res)
1382  {
1383  while ($rec = $this->db->fetch_array($res))
1384  {
1385  if ($rec['fk_parent'] > 0)
1386  {
1387  $cat = new Categorie($this->db);
1388  $cat->fetch($rec['fk_parent']);
1389  $parents[] = $cat;
1390  }
1391  }
1392  return $parents;
1393  }
1394  else
1395  {
1396  dol_print_error($this->db);
1397  return -1;
1398  }
1399  }
1400 
1407  function get_all_ways()
1408  {
1409  $ways = array();
1410 
1411  $parents=$this->get_meres();
1412  if (! empty($parents))
1413  {
1414  foreach ($parents as $parent)
1415  {
1416  $allways=$parent->get_all_ways();
1417  foreach ($allways as $way)
1418  {
1419  $w = $way;
1420  $w[] = $this;
1421  $ways[] = $w;
1422  }
1423  }
1424  }
1425 
1426  if (count($ways) == 0)
1427  $ways[0][0] = $this;
1428 
1429  return $ways;
1430  }
1431 
1442  function containing($id, $type, $mode='object')
1443  {
1444  $cats = array();
1445 
1446  if (is_numeric($type)) $type = Categorie::$MAP_ID_TO_CODE[$type];
1447 
1448  if ($type === Categorie::TYPE_BANK_LINE) // TODO Remove this with standard category code
1449  {
1450  // Load bank groups
1451  $sql = "SELECT c.label, c.rowid";
1452  $sql.= " FROM ".MAIN_DB_PREFIX."bank_class as a, ".MAIN_DB_PREFIX."bank_categ as c";
1453  $sql.= " WHERE a.lineid=".$id." AND a.fk_categ = c.rowid";
1454  $sql.= " ORDER BY c.label";
1455 
1456  $res = $this->db->query($sql);
1457  if ($res)
1458  {
1459  while ($obj = $this->db->fetch_object($res))
1460  {
1461  if ($mode == 'id') {
1462  $cats[] = $obj->rowid;
1463  } else if ($mode == 'label') {
1464  $cats[] = $obj->label;
1465  } else {
1466  $cat = new Categorie($this->db);
1467  $cat->id = $obj->rowid;
1468  $cat->label = $obj->label;
1469  $cats[] = $cat;
1470  }
1471  }
1472  }
1473  else
1474  {
1475  dol_print_error($this->db);
1476  return -1;
1477  }
1478  }
1479  else
1480  {
1481  $sql = "SELECT ct.fk_categorie, c.label, c.rowid";
1482  $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type] . " as ct, " . MAIN_DB_PREFIX . "categorie as c";
1483  $sql .= " WHERE ct.fk_categorie = c.rowid AND ct.fk_" . $this->MAP_CAT_FK[$type] . " = " . (int) $id . " AND c.type = " . $this->MAP_ID[$type];
1484  $sql .= " AND c.entity IN (" . getEntity( 'category', 1 ) . ")";
1485 
1486  $res = $this->db->query($sql);
1487  if ($res)
1488  {
1489  while ($obj = $this->db->fetch_object($res))
1490  {
1491  if ($mode == 'id') {
1492  $cats[] = $obj->rowid;
1493  } else if ($mode == 'label') {
1494  $cats[] = $obj->label;
1495  } else {
1496  $cat = new Categorie($this->db);
1497  $cat->fetch($obj->fk_categorie);
1498  $cats[] = $cat;
1499  }
1500  }
1501  }
1502  else
1503  {
1504  dol_print_error($this->db);
1505  return -1;
1506  }
1507  }
1508 
1509  return $cats;
1510  }
1511 
1512 
1524  function rechercher($id, $nom, $type, $exact = false, $case = false)
1525  {
1526  // Deprecation warning
1527  if (is_numeric($type)) {
1528  dol_syslog(__METHOD__ . ': using numeric types is deprecated.', LOG_WARNING);
1529  }
1530 
1531  $cats = array();
1532 
1533  // For backward compatibility
1534  if (is_numeric($type)) {
1535  // We want to reverse lookup
1536  $map_type = array_flip( $this->MAP_ID );
1537  $type = $map_type[$type];
1538  dol_syslog( get_class( $this ) . "::rechercher(): numeric types are deprecated, please use string instead",
1539  LOG_WARNING );
1540  }
1541 
1542  // Generation requete recherche
1543  $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "categorie";
1544  $sql .= " WHERE type = " . $this->MAP_ID[$type];
1545  $sql .= " AND entity IN (" . getEntity( 'category', 1 ) . ")";
1546  if ($nom)
1547  {
1548  if (! $exact)
1549  $nom = '%'.str_replace('*', '%', $nom).'%';
1550  if (! $case)
1551  $sql.= " AND label LIKE '".$this->db->escape($nom)."'";
1552  else
1553  $sql.= " AND label LIKE BINARY '".$this->db->escape($nom)."'";
1554  }
1555  if ($id)
1556  {
1557  $sql.=" AND rowid = '".$id."'";
1558  }
1559 
1560  $res = $this->db->query($sql);
1561  if ($res)
1562  {
1563  while ($rec = $this->db->fetch_array($res))
1564  {
1565  $cat = new Categorie($this->db);
1566  $cat->fetch($rec['rowid']);
1567  $cats[] = $cat;
1568  }
1569 
1570  return $cats;
1571  }
1572  else
1573  {
1574  $this->error=$this->db->error().' sql='.$sql;
1575  return -1;
1576  }
1577  }
1578 
1588  function getNomUrl($withpicto=0,$option='',$maxlength=0)
1589  {
1590  global $langs;
1591 
1592  $result='';
1593  $label=$langs->trans("ShowCategory").': '. ($this->ref?$this->ref:$this->label);
1594 
1595  // Check contrast with background and correct text color
1596  $forced_color='categtextwhite';
1597  if ($this->color)
1598  {
1599  if (colorIsLight($this->color)) $forced_color='categtextblack';
1600  }
1601 
1602  $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 .'">';
1603  $linkend='</a>';
1604 
1605  $picto='category';
1606 
1607 
1608  if ($withpicto) $result.=($link.img_object($label, $picto, 'class="classfortooltip"').$linkend);
1609  if ($withpicto && $withpicto != 2) $result.=' ';
1610  if ($withpicto != 2) $result.=$link.dol_trunc(($this->ref?$this->ref:$this->label),$maxlength).$linkend;
1611  return $result;
1612  }
1613 
1614 
1622  function add_photo($sdir, $file)
1623  {
1624  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1625 
1626  $dir = $sdir .'/'. get_exdir($this->id,2,0,0,$this,'category') . $this->id ."/";
1627  $dir .= "photos/";
1628 
1629  if (! file_exists($dir))
1630  {
1631  dol_mkdir($dir);
1632  }
1633 
1634  if (file_exists($dir)) {
1635  if (is_array($file['name']) && count($file['name']) > 0)
1636  {
1637  $nbfile = count($file['name']);
1638  for ($i = 0; $i <= $nbfile; $i ++) {
1639 
1640  $originImage = $dir . $file['name'][$i];
1641 
1642  // Cree fichier en taille origine
1643  dol_move_uploaded_file($file['tmp_name'][$i], $originImage, 1, 0, 0);
1644 
1645  if (file_exists($originImage)) {
1646  // Create thumbs
1647  $this->addThumbs($originImage);
1648  }
1649  }
1650  } else {
1651  $originImage = $dir . $file['name'];
1652 
1653  // Cree fichier en taille origine
1654  dol_move_uploaded_file($file['tmp_name'], $originImage, 1, 0, 0);
1655 
1656  if (file_exists($originImage)) {
1657  // Create thumbs
1658  $this->addThumbs($originImage);
1659  }
1660  }
1661  }
1662  }
1663 
1671  function liste_photos($dir,$nbmax=0)
1672  {
1673  include_once DOL_DOCUMENT_ROOT .'/core/lib/files.lib.php';
1674 
1675  $nbphoto=0;
1676  $tabobj=array();
1677 
1678  $dirthumb = $dir.'thumbs/';
1679 
1680  if (file_exists($dir))
1681  {
1682  $handle=opendir($dir);
1683  if (is_resource($handle))
1684  {
1685  while (($file = readdir($handle)) !== false)
1686  {
1687  if (dol_is_file($dir.$file) && preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$dir.$file))
1688  {
1689  $nbphoto++;
1690  $photo = $file;
1691 
1692  // On determine nom du fichier vignette
1693  $photo_vignette='';
1694  if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$photo,$regs))
1695  {
1696  $photo_vignette=preg_replace('/'.$regs[0].'/i','',$photo).'_small'.$regs[0];
1697  }
1698 
1699  // Objet
1700  $obj=array();
1701  $obj['photo']=$photo;
1702  if ($photo_vignette && is_file($dirthumb.$photo_vignette)) $obj['photo_vignette']='thumbs/' . $photo_vignette;
1703  else $obj['photo_vignette']="";
1704 
1705  $tabobj[$nbphoto-1]=$obj;
1706 
1707  // On continue ou on arrete de boucler
1708  if ($nbmax && $nbphoto >= $nbmax) break;
1709  }
1710  }
1711 
1712  closedir($handle);
1713  }
1714  }
1715 
1716  return $tabobj;
1717  }
1718 
1725  function delete_photo($file)
1726  {
1727  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1728 
1729  $dir = dirname($file).'/'; // Chemin du dossier contenant l'image d'origine
1730  $dirthumb = $dir.'/thumbs/'; // Chemin du dossier contenant la vignette
1731  $filename = preg_replace('/'.preg_quote($dir,'/').'/i','',$file); // Nom du fichier
1732 
1733  // On efface l'image d'origine
1734  dol_delete_file($file,1);
1735 
1736  // Si elle existe, on efface la vignette
1737  if (preg_match('/(\.jpeg|\.jpg|\.bmp|\.gif|\.png|\.tiff)$/i',$filename,$regs))
1738  {
1739  $photo_vignette=preg_replace('/'.$regs[0].'/i','',$filename).'_small'.$regs[0];
1740  if (file_exists($dirthumb.$photo_vignette))
1741  {
1742  dol_delete_file($dirthumb.$photo_vignette,1);
1743  }
1744  }
1745  }
1746 
1753  function get_image_size($file)
1754  {
1755  $infoImg = getimagesize($file); // Recuperation des infos de l'image
1756  $this->imgWidth = $infoImg[0]; // Largeur de l'image
1757  $this->imgHeight = $infoImg[1]; // Hauteur de l'image
1758  }
1759 
1767  function setMultiLangs($user)
1768  {
1769  global $langs;
1770 
1771  $langs_available = $langs->get_available_languages();
1772  $current_lang = $langs->getDefaultLang();
1773 
1774  foreach ($langs_available as $key => $value)
1775  {
1776  $sql = "SELECT rowid";
1777  $sql.= " FROM ".MAIN_DB_PREFIX."categorie_lang";
1778  $sql.= " WHERE fk_category=".$this->id;
1779  $sql.= " AND lang='".$key."'";
1780 
1781  $result = $this->db->query($sql);
1782 
1783  if ($key == $current_lang)
1784  {
1785  if ($this->db->num_rows($result)) // si aucune ligne dans la base
1786  {
1787  $sql2 = "UPDATE ".MAIN_DB_PREFIX."categorie_lang";
1788  $sql2.= " SET label='".$this->db->escape($this->label)."',";
1789  $sql2.= " description='".$this->db->escape($this->description)."'";
1790  $sql2.= " WHERE fk_category=".$this->id." AND lang='".$this->db->escape($key)."'";
1791  }
1792  else
1793  {
1794  $sql2 = "INSERT INTO ".MAIN_DB_PREFIX."categorie_lang (fk_category, lang, label, description)";
1795  $sql2.= " VALUES(".$this->id.",'".$key."','". $this->db->escape($this->label);
1796  $sql2.= "','".$this->db->escape($this->multilangs["$key"]["description"])."')";
1797  }
1798  dol_syslog(get_class($this).'::setMultiLangs', LOG_DEBUG);
1799  if (! $this->db->query($sql2))
1800  {
1801  $this->error=$this->db->lasterror();
1802  return -1;
1803  }
1804  }
1805  else if (isset($this->multilangs["$key"]))
1806  {
1807  if ($this->db->num_rows($result)) // si aucune ligne dans la base
1808  {
1809  $sql2 = "UPDATE ".MAIN_DB_PREFIX."categorie_lang";
1810  $sql2.= " SET label='".$this->db->escape($this->multilangs["$key"]["label"])."',";
1811  $sql2.= " description='".$this->db->escape($this->multilangs["$key"]["description"])."'";
1812  $sql2.= " WHERE fk_category=".$this->id." AND lang='".$this->db->escape($key)."'";
1813  }
1814  else
1815  {
1816  $sql2 = "INSERT INTO ".MAIN_DB_PREFIX."categorie_lang (fk_category, lang, label, description)";
1817  $sql2.= " VALUES(".$this->id.",'".$key."','". $this->db->escape($this->multilangs["$key"]["label"]);
1818  $sql2.= "','".$this->db->escape($this->multilangs["$key"]["description"])."')";
1819  }
1820 
1821  // on ne sauvegarde pas des champs vides
1822  if ( $this->multilangs["$key"]["label"] || $this->multilangs["$key"]["description"] || $this->multilangs["$key"]["note"] )
1823  dol_syslog(get_class($this).'::setMultiLangs', LOG_DEBUG);
1824  if (! $this->db->query($sql2))
1825  {
1826  $this->error=$this->db->lasterror();
1827  return -1;
1828  }
1829  }
1830  }
1831 
1832  // Call trigger
1833  $result = $this->call_trigger('CATEGORY_SET_MULTILANGS',$user);
1834  if ($result < 0) {
1835  $this->error = $this->db->lasterror();
1836  return -1;
1837  }
1838  // End call triggers
1839 
1840  return 1;
1841  }
1842 
1848  function getMultiLangs()
1849  {
1850  global $langs;
1851 
1852  $current_lang = $langs->getDefaultLang();
1853 
1854  $sql = "SELECT lang, label, description";
1855  $sql.= " FROM ".MAIN_DB_PREFIX."categorie_lang";
1856  $sql.= " WHERE fk_category=".$this->id;
1857 
1858  $result = $this->db->query($sql);
1859  if ($result)
1860  {
1861  while ( $obj = $this->db->fetch_object($result) )
1862  {
1863  //print 'lang='.$obj->lang.' current='.$current_lang.'<br>';
1864  if( $obj->lang == $current_lang ) // si on a les traduct. dans la langue courante on les charge en infos principales.
1865  {
1866  $this->label = $obj->label;
1867  $this->description = $obj->description;
1868 
1869  }
1870  $this->multilangs["$obj->lang"]["label"] = $obj->label;
1871  $this->multilangs["$obj->lang"]["description"] = $obj->description;
1872  }
1873  return 1;
1874  }
1875  else
1876  {
1877  $this->error=$langs->trans("Error")." : ".$this->db->error()." - ".$sql;
1878  return -1;
1879  }
1880  }
1881 
1888  function getLibStatut($mode)
1889  {
1890  return '';
1891  }
1892 
1893 
1901  function initAsSpecimen()
1902  {
1903  dol_syslog(get_class($this)."::initAsSpecimen");
1904 
1905  // Initialise parametres
1906  $this->id=0;
1907  $this->fk_parent=0;
1908  $this->label = 'SPECIMEN';
1909  $this->specimen=1;
1910  $this->description = 'This is a description';
1911  $this->socid = 1;
1912  $this->type = self::TYPE_PRODUCT;
1913  }
1914 
1923  public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
1924  {
1925  $tables = array(
1926  'categorie_societe'
1927  );
1928 
1929  return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables, 1);
1930  }
1931 }
getMultiLangs()
Load array this->multilangs.
static replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
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:962
addThumbs($file)
Build thumb.
create($user)
Add category into database.
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.
</td >< tdclass="liste_titre"align="right"></td ></tr >< trclass="liste_titre">< inputtype="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< trclass="oddeven">< td >< inputtype="checkbox"class="check"name="'.$i.'"'.$disabled.'></td >< td >< inputtype="checkbox"class="check"name="choose'.$i.'"></td >< tdclass="nowrap"></td >< td >< inputtype="hidden"name="desc'.$i.'"value="'.dol_escape_htmltag($objp-> description
Only used if Module[ID]Desc translation string is not found.
Definition: replenish.php:554
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:39
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.
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.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
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.
getEntity($element, $shared=1, $forceentity=null)
Get list of entity id to use.
__construct($db)
Constructor.
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('id','id_mere',...) 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.
getListForItem($id, $type='customer', $sortfield="s.rowid", $sortorder= 'ASC', $limit=0, $page=0)
List categories of an element 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:427
print
Draft customers invoices.
Definition: index.php:91
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)
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:1013
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null)
Remove a file or several files with a mask.
Definition: files.lib.php:1103
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.
get_nb_categories()
Returns total number of categories.
add_type($obj, $type)
Link an object to the category.
colorIsLight($stringcolor)
Return true if the color is light.
type
Definition: viewcat.php:283
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's parent or root and for this cat'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.