dolibarr  7.0.0-beta
extrafields.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org>
4  * Copyright (C) 2004 Sebastien Di Cintio <sdicintio@ressource-toi.org>
5  * Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
6  * Copyright (C) 2009-2012 Laurent Destailleur <eldy@users.sourceforge.net>
7  * Copyright (C) 2009-2012 Regis Houssin <regis.houssin@capnetworks.com>
8  * Copyright (C) 2013 Florian Henry <forian.henry@open-concept.pro>
9  * Copyright (C) 2015 Charles-Fr BENKE <charles.fr@benke.fr>
10  * Copyright (C) 2016 RaphaĆ«l Doursenaud <rdoursenaud@gpcsolutions.fr>
11  * Copyright (C) 2017 Nicolas ZABOURI <info@inovea-conseil.com>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program. If not, see <http://www.gnu.org/licenses/>.
25  */
26 
38 {
39  var $db;
40 
41  // type of element (for what object is the extrafield)
42  var $attribute_elementtype;
43 
44  // Array with type of the extra field
45  var $attribute_type;
46  // Array with label of extra field
47  var $attribute_label;
48  // Array with size of extra field
49  var $attribute_size;
50  // array with list of possible values for some types of extra fields
51  var $attribute_choice;
52  // Array to store compute formula for computed fields
53  var $attribute_computed;
54  // Array to store default value
55  var $attribute_default;
56  // Array to store if attribute is unique or not
57  var $attribute_unique;
58  // Array to store if attribute is required or not
59  var $attribute_required;
60  // Array to store parameters of attribute (used in select type)
61  var $attribute_param;
62  // Array to store position of attribute
63  var $attribute_pos;
64  // Array to store if attribute is editable regardless of the document status
65  var $attribute_alwayseditable;
66  // Array to store permission to check
67  var $attribute_perms;
68  // Array to store language file to translate label of values
69  var $attribute_langfile;
70  // Array to store if field is visible by default on list
71  var $attribute_list;
72  // Array to store if extra field is hidden
73  var $attribute_hidden; // warning, do not rely on this. If your module need a hidden data, it must use its own table.
74 
75  // New array to store extrafields definition
76  var $attributes;
77 
78  var $error;
79  var $errno;
80 
81 
82  public static $type2label=array(
83  'varchar'=>'String',
84  'text'=>'TextLong',
85  'int'=>'Int',
86  'double'=>'Float',
87  'date'=>'Date',
88  'datetime'=>'DateAndTime',
89  'boolean'=>'Boolean',
90  'price'=>'ExtrafieldPrice',
91  'phone'=>'ExtrafieldPhone',
92  'mail'=>'ExtrafieldMail',
93  'url'=>'ExtrafieldUrl',
94  'password' => 'ExtrafieldPassword',
95  'select' => 'ExtrafieldSelect',
96  'sellist' => 'ExtrafieldSelectList',
97  'radio' => 'ExtrafieldRadio',
98  'checkbox' => 'ExtrafieldCheckBox',
99  'chkbxlst' => 'ExtrafieldCheckBoxFromList',
100  'link' => 'ExtrafieldLink',
101  'separate' => 'ExtrafieldSeparator',
102  );
103 
104 
110  function __construct($db)
111  {
112  $this->db = $db;
113  $this->error = array();
114  $this->attribute_elementtype = array();
115  $this->attribute_type = array();
116  $this->attribute_label = array();
117  $this->attribute_size = array();
118  $this->attribute_computed = array();
119  $this->attribute_default = array();
120  $this->attribute_unique = array();
121  $this->attribute_required = array();
122  $this->attribute_perms = array();
123  $this->attribute_langfile = array();
124  $this->attribute_list = array();
125  $this->attribute_hidden = array();
126  }
127 
151  function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param='', $alwayseditable=0, $perms='', $list=-1, $ishidden=0, $computed='', $entity='', $langfile='', $enabled='1')
152  {
153  if (empty($attrname)) return -1;
154  if (empty($label)) return -1;
155 
156  if ($elementtype == 'thirdparty') $elementtype='societe';
157  if ($elementtype == 'contact') $elementtype='socpeople';
158 
159  // Create field into database except for separator type which is not stored in database
160  if ($type != 'separate')
161  {
162  $result=$this->create($attrname, $type, $size, $elementtype, $unique, $required, $default_value, $param, $perms, $list, $computed);
163  }
164  $err1=$this->errno;
165  if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate')
166  {
167  // Add declaration of field into table
168  $result2=$this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $ishidden, $default, $computed, $entity, $langfile, $enabled);
169  $err2=$this->errno;
170  if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS'))
171  {
172  $this->error='';
173  $this->errno=0;
174  return 1;
175  }
176  else return -2;
177  }
178  else
179  {
180  return -1;
181  }
182  }
183 
201  private function create($attrname, $type='varchar', $length=255, $elementtype='member', $unique=0, $required=0, $default_value='',$param='', $perms='', $list=0, $computed='')
202  {
203  if ($elementtype == 'thirdparty') $elementtype='societe';
204  if ($elementtype == 'contact') $elementtype='socpeople';
205 
206  $table=$elementtype.'_extrafields';
207  if ($elementtype == 'categorie') $table='categories_extrafields';
208 
209  if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9_]*$/",$attrname) && ! is_numeric($attrname))
210  {
211  if ($type=='boolean') {
212  $typedb='int';
213  $lengthdb='1';
214  } elseif($type=='price') {
215  $typedb='double';
216  $lengthdb='24,8';
217  } elseif($type=='phone') {
218  $typedb='varchar';
219  $lengthdb='20';
220  } elseif($type=='mail') {
221  $typedb='varchar';
222  $lengthdb='128';
223  } elseif($type=='url') {
224  $typedb='varchar';
225  $lengthdb='255';
226  } elseif (($type=='select') || ($type=='sellist') || ($type=='radio') ||($type=='checkbox') ||($type=='chkbxlst')){
227  $typedb='text';
228  $lengthdb='';
229  } elseif ($type=='link') {
230  $typedb='int';
231  $lengthdb='11';
232  } elseif($type=='password') {
233  $typedb='varchar';
234  $lengthdb='50';
235  } else {
236  $typedb=$type;
237  $lengthdb=$length;
238  if ($type == 'varchar' && empty($lengthdb)) $lengthdb='255';
239  }
240  $field_desc = array(
241  'type'=>$typedb,
242  'value'=>$lengthdb,
243  'null'=>($required?'NOT NULL':'NULL'),
244  'default' => $default_value
245  );
246 
247  $result=$this->db->DDLAddField(MAIN_DB_PREFIX.$table, $attrname, $field_desc);
248  if ($result > 0)
249  {
250  if ($unique)
251  {
252  $sql="ALTER TABLE ".MAIN_DB_PREFIX.$table." ADD UNIQUE INDEX uk_".$table."_".$attrname." (".$attrname.")";
253  $resql=$this->db->query($sql,1,'dml');
254  }
255  return 1;
256  }
257  else
258  {
259  $this->error=$this->db->lasterror();
260  $this->errno=$this->db->lasterrno();
261  return -1;
262  }
263  }
264  else
265  {
266  return 0;
267  }
268  }
269 
293  private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list=-1, $ishidden=0, $default='', $computed='',$entity='', $langfile='', $enabled='1')
294  {
295  global $conf,$user;
296 
297  if ($elementtype == 'thirdparty') $elementtype='societe';
298  if ($elementtype == 'contact') $elementtype='socpeople';
299 
300  // Clean parameters
301  if (empty($pos)) $pos=0;
302  if (empty($list)) $list=0;
303  if (empty($required)) $required=0;
304  if (empty($unique)) $unique=0;
305  if (empty($alwayseditable)) $alwayseditable=0;
306 
307  if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname) && ! is_numeric($attrname))
308  {
309  if(is_array($param) && count($param) > 0)
310  {
311  $params = $this->db->escape(serialize($param));
312  }
313  elseif (strlen($param) > 0)
314  {
315  $params = trim($param);
316  }
317  else
318  {
319  $params='';
320  }
321 
322  $sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(";
323  $sql.= " name,";
324  $sql.= " label,";
325  $sql.= " type,";
326  $sql.= " pos,";
327  $sql.= " size,";
328  $sql.= " entity,";
329  $sql.= " elementtype,";
330  $sql.= " fieldunique,";
331  $sql.= " fieldrequired,";
332  $sql.= " param,";
333  $sql.= " alwayseditable,";
334  $sql.= " perms,";
335  $sql.= " langs,";
336  $sql.= " list,";
337  $sql.= " fielddefault,";
338  $sql.= " fieldcomputed,";
339  $sql.= " fk_user_author,";
340  $sql.= " fk_user_modif,";
341  $sql.= " datec,";
342  $sql.= " enabled";
343  $sql.= " )";
344  $sql.= " VALUES('".$attrname."',";
345  $sql.= " '".$this->db->escape($label)."',";
346  $sql.= " '".$this->db->escape($type)."',";
347  $sql.= " ".$pos.",";
348  $sql.= " '".$this->db->escape($size)."',";
349  $sql.= " ".($entity===''?$conf->entity:$entity).",";
350  $sql.= " '".$this->db->escape($elementtype)."',";
351  $sql.= " ".$unique.",";
352  $sql.= " ".$required.",";
353  $sql.= " '".$this->db->escape($params)."',";
354  $sql.= " ".$alwayseditable.",";
355  $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null").",";
356  $sql.= " ".($langfile?"'".$this->db->escape($langfile)."'":"null").",";
357  $sql.= " ".$list.",";
358  $sql.= " ".($default?"'".$this->db->escape($default)."'":"null").",";
359  $sql.= " ".($computed?"'".$this->db->escape($computed)."'":"null").",";
360  $sql .= " " . $user->id . ",";
361  $sql .= " " . $user->id . ",";
362  $sql .= "'" . $this->db->idate(dol_now()) . "',";
363  $sql.= " ".($enabled?"'".$this->db->escape($enabled)."'":"1");
364  $sql.=')';
365 
366  dol_syslog(get_class($this)."::create_label", LOG_DEBUG);
367  if ($this->db->query($sql))
368  {
369  return 1;
370  }
371  else
372  {
373  $this->error=$this->db->lasterror();
374  $this->errno=$this->db->lasterrno();
375  return -1;
376  }
377  }
378  }
379 
387  function delete($attrname, $elementtype='member')
388  {
389  if ($elementtype == 'thirdparty') $elementtype='societe';
390  if ($elementtype == 'contact') $elementtype='socpeople';
391 
392  $table=$elementtype.'_extrafields';
393  if ($elementtype == 'categorie') $table='categories_extrafields';
394 
395  $error=0;
396 
397  if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
398  {
399  $result=$this->delete_label($attrname,$elementtype);
400  if ($result < 0)
401  {
402  $this->error=$this->db->lasterror();
403  $error++;
404  }
405 
406  if (! $error)
407  {
408  $sql = "SELECT COUNT(rowid) as nb";
409  $sql.= " FROM ".MAIN_DB_PREFIX."extrafields";
410  $sql.= " WHERE elementtype = '".$elementtype."'";
411  $sql.= " AND name = '".$attrname."'";
412  //$sql.= " AND entity IN (0,".$conf->entity.")"; Do not test on entity here. We want to see if there is still on field remaning in other entities before deleting field in table
413  $resql = $this->db->query($sql);
414  if ($resql)
415  {
416  $obj = $this->db->fetch_object($resql);
417  if ($obj->nb <= 0)
418  {
419  $result=$this->db->DDLDropField(MAIN_DB_PREFIX.$table,$attrname); // This also drop the unique key
420  if ($result < 0)
421  {
422  $this->error=$this->db->lasterror();
423  $error++;
424  }
425  }
426  }
427  }
428 
429  return $result;
430  }
431  else
432  {
433  return 0;
434  }
435 
436  }
437 
445  private function delete_label($attrname, $elementtype='member')
446  {
447  global $conf;
448 
449  if ($elementtype == 'thirdparty') $elementtype='societe';
450  if ($elementtype == 'contact') $elementtype='socpeople';
451 
452  if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
453  {
454  $sql = "DELETE FROM ".MAIN_DB_PREFIX."extrafields";
455  $sql.= " WHERE name = '".$attrname."'";
456  $sql.= " AND entity IN (0,".$conf->entity.')';
457  $sql.= " AND elementtype = '".$elementtype."'";
458 
459  dol_syslog(get_class($this)."::delete_label", LOG_DEBUG);
460  $resql=$this->db->query($sql);
461  if ($resql)
462  {
463  return 1;
464  }
465  else
466  {
467  print dol_print_error($this->db);
468  return -1;
469  }
470  }
471  else
472  {
473  return 0;
474  }
475 
476  }
477 
501  function update($attrname, $label, $type, $length, $elementtype, $unique=0, $required=0, $pos=0, $param='', $alwayseditable=0, $perms='', $list='', $ishidden=0, $default='', $computed='', $entity='', $langfile='', $enabled='1')
502  {
503  if ($elementtype == 'thirdparty') $elementtype='societe';
504  if ($elementtype == 'contact') $elementtype='socpeople';
505 
506  $table=$elementtype.'_extrafields';
507  if ($elementtype == 'categorie') $table='categories_extrafields';
508 
509  if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
510  {
511  if ($type=='boolean') {
512  $typedb='int';
513  $lengthdb='1';
514  } elseif($type=='price') {
515  $typedb='double';
516  $lengthdb='24,8';
517  } elseif($type=='phone') {
518  $typedb='varchar';
519  $lengthdb='20';
520  } elseif($type=='mail') {
521  $typedb='varchar';
522  $lengthdb='128';
523  } elseif($type=='url') {
524  $typedb='varchar';
525  $lengthdb='255';
526  } elseif (($type=='select') || ($type=='sellist') || ($type=='radio') || ($type=='checkbox') || ($type=='chkbxlst')) {
527  $typedb='text';
528  $lengthdb='';
529  } elseif ($type=='link') {
530  $typedb='int';
531  $lengthdb='11';
532  } elseif($type=='password') {
533  $typedb='varchar';
534  $lengthdb='50';
535  } else {
536  $typedb=$type;
537  $lengthdb=$length;
538  }
539  $field_desc = array('type'=>$typedb, 'value'=>$lengthdb, 'null'=>($required?'NOT NULL':'NULL'), 'default'=>$default);
540 
541  if ($type != 'separate') // No table update when separate type
542  {
543  $result=$this->db->DDLUpdateField(MAIN_DB_PREFIX.$table, $attrname, $field_desc);
544  }
545  if ($result > 0 || $type == 'separate')
546  {
547  if ($label)
548  {
549  $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms,$list,$ishidden,$default,$computed,$entity,$langfile,$enabled);
550  }
551  if ($result > 0)
552  {
553  $sql='';
554  if ($unique)
555  {
556  $sql="ALTER TABLE ".MAIN_DB_PREFIX.$table." ADD UNIQUE INDEX uk_".$table."_".$attrname." (".$attrname.")";
557  }
558  else
559  {
560  $sql="ALTER TABLE ".MAIN_DB_PREFIX.$table." DROP INDEX uk_".$table."_".$attrname;
561  }
562  dol_syslog(get_class($this).'::update', LOG_DEBUG);
563  $resql=$this->db->query($sql,1,'dml');
564  return 1;
565  }
566  else
567  {
568  $this->error=$this->db->lasterror();
569  return -1;
570  }
571  }
572  else
573  {
574  $this->error=$this->db->lasterror();
575  return -1;
576  }
577  }
578  else
579  {
580  return 0;
581  }
582 
583  }
584 
608  private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='',$list=0,$ishidden=0,$default='',$computed='',$entity='',$langfile='',$enabled='1')
609  {
610  global $conf, $user;
611  dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$ishidden.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled);
612 
613  // Clean parameters
614  if ($elementtype == 'thirdparty') $elementtype='societe';
615  if ($elementtype == 'contact') $elementtype='socpeople';
616 
617  if (empty($pos)) $pos=0;
618  if (empty($list)) $list=0;
619  if (empty($required)) $required=0;
620  if (empty($unique)) $unique=0;
621  if (empty($alwayseditable)) $alwayseditable=0;
622 
623  if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
624  {
625  $this->db->begin();
626 
627  if (is_array($param))
628  {
629  if (count($param) > 0) $param = $this->db->escape(serialize($param));
630  else $param='';
631  }
632 
633  $sql_del = "DELETE FROM ".MAIN_DB_PREFIX."extrafields";
634  $sql_del.= " WHERE name = '".$attrname."'";
635  $sql_del.= " AND entity = ".($entity===''?$conf->entity:$entity);
636  $sql_del.= " AND elementtype = '".$elementtype."'";
637 
638  $resql1=$this->db->query($sql_del);
639 
640  $sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(";
641  $sql.= " name,"; // This is code
642  $sql.= " entity,";
643  $sql.= " label,";
644  $sql.= " type,";
645  $sql.= " size,";
646  $sql.= " elementtype,";
647  $sql.= " fieldunique,";
648  $sql.= " fieldrequired,";
649  $sql.= " perms,";
650  $sql.= " langs,";
651  $sql.= " pos,";
652  $sql.= " alwayseditable,";
653  $sql.= " param,";
654  $sql.= " list,";
655  $sql.= " fielddefault,";
656  $sql.= " fieldcomputed,";
657  $sql.= " fk_user_author,";
658  $sql.= " fk_user_modif,";
659  $sql.= " datec,";
660  $sql.= " enabled";
661  $sql.= ") VALUES (";
662  $sql.= "'".$attrname."',";
663  $sql.= " ".($entity===''?$conf->entity:$entity).",";
664  $sql.= " '".$this->db->escape($label)."',";
665  $sql.= " '".$this->db->escape($type)."',";
666  $sql.= " '".$this->db->escape($size)."',";
667  $sql.= " '".$this->db->escape($elementtype)."',";
668  $sql.= " ".$unique.",";
669  $sql.= " ".$required.",";
670  $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null").",";
671  $sql.= " ".($langfile?"'".$this->db->escape($langfile)."'":"null").",";
672  $sql.= " ".$pos.",";
673  $sql.= " '".$this->db->escape($alwayseditable)."',";
674  $sql.= " '".$this->db->escape($param)."',";
675  $sql.= " ".$list.", ";
676  $sql.= " ".(($default!='')?"'".$this->db->escape($default)."'":"null").",";
677  $sql.= " ".($computed?"'".$this->db->escape($computed)."'":"null").",";
678  $sql .= " " . $user->id . ",";
679  $sql .= " " . $user->id . ",";
680  $sql .= "'" . $this->db->idate(dol_now()) . "',";
681  $sql .= "'" . $this->db->escape($enabled). "'";
682  $sql.= ")";
683 
684  $resql2=$this->db->query($sql);
685 
686  if ($resql1 && $resql2)
687  {
688  $this->db->commit();
689  return 1;
690  }
691  else
692  {
693  $this->db->rollback();
694  print dol_print_error($this->db);
695  return -1;
696  }
697  }
698  else
699  {
700  return 0;
701  }
702  }
703 
704 
712  function fetch_name_optionals_label($elementtype,$forceload=false)
713  {
714  global $conf;
715 
716  if (empty($elementtype) ) return array();
717 
718  if ($elementtype == 'thirdparty') $elementtype='societe';
719  if ($elementtype == 'contact') $elementtype='socpeople';
720 
721  $array_name_label=array();
722 
723  // To avoid conflicts with external modules. TODO Remove this.
724  if (!$forceload && !empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) return $array_name_label;
725 
726  // We should not have several time this log. If we have, there is some optimization to do by calling a simple $object->fetch_optionals() that include cache management.
727  dol_syslog("fetch_name_optionals_label elementtype=".$elementtype);
728 
729  $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,fielddefault,fieldcomputed";
730  $sql .= ",entity";
731  $sql.= " FROM ".MAIN_DB_PREFIX."extrafields";
732  $sql.= " WHERE entity IN (0,".$conf->entity.")";
733  if ($elementtype) $sql.= " AND elementtype = '".$elementtype."'";
734  $sql.= " ORDER BY pos";
735 
736  $resql=$this->db->query($sql);
737  if ($resql)
738  {
739  if ($this->db->num_rows($resql))
740  {
741  while ($tab = $this->db->fetch_object($resql))
742  {
743  // We can add this attribute to object. TODO Remove this and return $this->attributes[$elementtype]['label']
744  if ($tab->type != 'separate')
745  {
746  $array_name_label[$tab->name]=$tab->label;
747  }
748 
749  // Old usage
750  $this->attribute_type[$tab->name]=$tab->type;
751  $this->attribute_label[$tab->name]=$tab->label;
752  $this->attribute_size[$tab->name]=$tab->size;
753  $this->attribute_elementtype[$tab->name]=$tab->elementtype;
754  $this->attribute_default[$tab->name]=$tab->fielddefault;
755  $this->attribute_computed[$tab->name]=$tab->fieldcomputed;
756  $this->attribute_unique[$tab->name]=$tab->fieldunique;
757  $this->attribute_required[$tab->name]=$tab->fieldrequired;
758  $this->attribute_param[$tab->name]=($tab->param ? unserialize($tab->param) : '');
759  $this->attribute_pos[$tab->name]=$tab->pos;
760  $this->attribute_alwayseditable[$tab->name]=$tab->alwayseditable;
761  $this->attribute_perms[$tab->name]=(strlen($tab->perms) == 0 ? 1 : $tab->perms);
762  $this->attribute_langfile[$tab->name]=$tab->langs;
763  $this->attribute_list[$tab->name]=$tab->list;
764  $this->attribute_entityid[$tab->name]=$tab->entity;
765 
766  // New usage
767  $this->attributes[$tab->elementtype]['type'][$tab->name]=$tab->type;
768  $this->attributes[$tab->elementtype]['label'][$tab->name]=$tab->label;
769  $this->attributes[$tab->elementtype]['size'][$tab->name]=$tab->size;
770  $this->attributes[$tab->elementtype]['elementtype'][$tab->name]=$tab->elementtype;
771  $this->attributes[$tab->elementtype]['default'][$tab->name]=$tab->fielddefault;
772  $this->attributes[$tab->elementtype]['computed'][$tab->name]=$tab->fieldcomputed;
773  $this->attributes[$tab->elementtype]['unique'][$tab->name]=$tab->fieldunique;
774  $this->attributes[$tab->elementtype]['required'][$tab->name]=$tab->fieldrequired;
775  $this->attributes[$tab->elementtype]['param'][$tab->name]=($tab->param ? unserialize($tab->param) : '');
776  $this->attributes[$tab->elementtype]['pos'][$tab->name]=$tab->pos;
777  $this->attributes[$tab->elementtype]['alwayseditable'][$tab->name]=$tab->alwayseditable;
778  $this->attributes[$tab->elementtype]['perms'][$tab->name]=(strlen($tab->perms) == 0 ? 1 : $tab->perms);
779  $this->attributes[$tab->elementtype]['langfile'][$tab->name]=$tab->langs;
780  $this->attributes[$tab->elementtype]['list'][$tab->name]=$tab->list;
781  $this->attributes[$tab->elementtype]['entityid'][$tab->name]=$tab->entity;
782 
783  if (!empty($conf->multicompany->enabled))
784  {
785  $sql_entity_name='SELECT label FROM '.MAIN_DB_PREFIX.'entity WHERE rowid='.$tab->entity;
786  $resql_entity_name=$this->db->query($sql_entity_name);
787  if ($resql_entity_name)
788  {
789  if ($this->db->num_rows($resql_entity_name))
790  {
791  if ($obj = $this->db->fetch_object($resql_entity_name))
792  {
793  $this->attribute_entitylabel[$tab->name]=$obj->label;
794  $this->attributes[$tab->elementtype]['entitylabel'][$tab->name]=$obj->label;
795  }
796  }
797  }
798  }
799  }
800  }
801  if ($elementtype) $this->attributes[$elementtype]['loaded']=1;
802  }
803  else
804  {
805  $this->error=$this->db->lasterror();
806  dol_syslog(get_class($this)."::fetch_name_optionals_label ".$this->error, LOG_ERR);
807  }
808 
809  return $array_name_label;
810  }
811 
812 
826  function showInputField($key, $value, $moreparam='', $keysuffix='', $keyprefix='', $showsize=0, $objectid=0)
827  {
828  global $conf,$langs,$form;
829 
830  if (! is_object($form))
831  {
832  require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
833  $form=new Form($this->db);
834  }
835 
836  $out='';
837 
838  $keyprefix = $keyprefix.'options_'; // Because we work on extrafields
839 
840  $label=$this->attribute_label[$key];
841  $type =$this->attribute_type[$key];
842  $size =$this->attribute_size[$key];
843  $elementtype=$this->attribute_elementtype[$key]; // Seems not used
844  $default=$this->attribute_default[$key];
845  $computed=$this->attribute_computed[$key];
846  $unique=$this->attribute_unique[$key];
847  $required=$this->attribute_required[$key];
848  $param=$this->attribute_param[$key];
849  $langfile=$this->attribute_langfile[$key];
850  $list=$this->attribute_list[$key];
851  $hidden=$this->attribute_hidden[$key];
852 
853  if ($computed)
854  {
855  if (! preg_match('/^search_/', $keyprefix)) return '<span class="opacitymedium">'.$langs->trans("AutomaticallyCalculated").'</span>';
856  else return '';
857  }
858 
859  if (empty($showsize))
860  {
861  if ($type == 'date')
862  {
863  //$showsize=10;
864  $showsize = 'minwidth100imp';
865  }
866  elseif ($type == 'datetime')
867  {
868  //$showsize=19;
869  $showsize = 'minwidth200imp';
870  }
871  elseif (in_array($type,array('int','integer','double','price')))
872  {
873  //$showsize=10;
874  $showsize = 'maxwidth75';
875  }
876  elseif ($type == 'url')
877  {
878  $showsize='minwidth400';
879  }
880  elseif ($type == 'boolean')
881  {
882  $showsize='';
883  }
884  else
885  {
886  if (round($size) < 12)
887  {
888  $showsize = 'minwidth100';
889  }
890  else if (round($size) <= 48)
891  {
892  $showsize = 'minwidth200';
893  }
894  else
895  {
896  //$showsize=48;
897  $showsize = 'minwidth400';
898  }
899  }
900  }
901 
902  if (in_array($type,array('date','datetime')))
903  {
904  $tmp=explode(',',$size);
905  $newsize=$tmp[0];
906 
907  $showtime = in_array($type,array('datetime')) ? 1 : 0;
908 
909  // Do not show current date when field not required (see select_date() method)
910  if (!$required && $value == '') $value = '-1';
911 
912  // TODO Must also support $moreparam
913  $out = $form->select_date($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 1, 0, 1);
914  }
915  elseif (in_array($type,array('int','integer')))
916  {
917  $tmp=explode(',',$size);
918  $newsize=$tmp[0];
919  $out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" maxlength="'.$newsize.'" value="'.dol_escape_htmltag($value).'"'.($moreparam?$moreparam:'').'>';
920  }
921  elseif (preg_match('/varchar/', $type))
922  {
923  $out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" maxlength="'.$size.'" value="'.dol_escape_htmltag($value).'"'.($moreparam?$moreparam:'').'>';
924  }
925  elseif (in_array($type, array('mail', 'phone', 'url')))
926  {
927  $out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam?$moreparam:'').'>';
928  }
929  elseif ($type == 'text')
930  {
931  if (! preg_match('/search_/', $keyprefix)) // If keyprefix is search_ or search_options_, we must just use a simple text field
932  {
933  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
934  $doleditor=new DolEditor($keyprefix.$key.$keysuffix,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,ROWS_5,'90%');
935  $out=$doleditor->Create(1);
936  }
937  else
938  {
939  $out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam?$moreparam:'').'>';
940  }
941  }
942  elseif ($type == 'boolean')
943  {
944  $checked='';
945  if (!empty($value)) {
946  $checked=' checked value="1" ';
947  } else {
948  $checked=' value="1" ';
949  }
950  $out='<input type="checkbox" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.$checked.' '.($moreparam?$moreparam:'').'>';
951  }
952  elseif ($type == 'price')
953  {
954  if (!empty($value)) { // $value in memory is a php numeric, we format it into user number format.
955  $value=price($value);
956  }
957  $out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam?$moreparam:'').'> '.$langs->getCurrencySymbol($conf->currency);
958  }
959  elseif ($type == 'double')
960  {
961  if (!empty($value)) { // $value in memory is a php numeric, we format it into user number format.
962  $value=price($value);
963  }
964  $out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam?$moreparam:'').'> ';
965  }
966  elseif ($type == 'select')
967  {
968  $out = '';
969  if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->MAIN_EXTRAFIELDS_USE_SELECT2))
970  {
971  include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
972  $out.= ajax_combobox($keyprefix.$key.$keysuffix, array(), 0);
973  }
974 
975  $out.='<select class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam?$moreparam:'').'>';
976  $out.='<option value="0">&nbsp;</option>';
977  foreach ($param['options'] as $key => $val)
978  {
979  if ((string) $key == '') continue;
980  list($val, $parent) = explode('|', $val);
981  $out.='<option value="'.$key.'"';
982  $out.= (((string) $value == (string) $key)?' selected':'');
983  $out.= (!empty($parent)?' parent="'.$parent.'"':'');
984  $out.='>'.$val.'</option>';
985  }
986  $out.='</select>';
987  }
988  elseif ($type == 'sellist')
989  {
990  $out = '';
991  if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->MAIN_EXTRAFIELDS_USE_SELECT2))
992  {
993  include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
994  $out.= ajax_combobox($keyprefix.$key.$keysuffix, array(), 0);
995  }
996 
997  $out.='<select class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam?$moreparam:'').'>';
998  if (is_array($param['options']))
999  {
1000  $param_list=array_keys($param['options']);
1001  $InfoFieldList = explode(":", $param_list[0]);
1002  $parentName='';
1003  $parentField='';
1004  // 0 : tableName
1005  // 1 : label field name
1006  // 2 : key fields name (if differ of rowid)
1007  // 3 : key field parent (for dependent lists)
1008  // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
1009  $keyList=(empty($InfoFieldList[2])?'rowid':$InfoFieldList[2].' as rowid');
1010 
1011 
1012  if (count($InfoFieldList) > 4 && ! empty($InfoFieldList[4]))
1013  {
1014  if (strpos($InfoFieldList[4], 'extra.') !== false)
1015  {
1016  $keyList='main.'.$InfoFieldList[2].' as rowid';
1017  } else {
1018  $keyList=$InfoFieldList[2].' as rowid';
1019  }
1020  }
1021  if (count($InfoFieldList) > 3 && ! empty($InfoFieldList[3]))
1022  {
1023  list($parentName, $parentField) = explode('|', $InfoFieldList[3]);
1024  $keyList.= ', '.$parentField;
1025  }
1026 
1027  $fields_label = explode('|',$InfoFieldList[1]);
1028  if (is_array($fields_label))
1029  {
1030  $keyList .=', ';
1031  $keyList .= implode(', ', $fields_label);
1032  }
1033 
1034  $sqlwhere='';
1035  $sql = 'SELECT '.$keyList;
1036  $sql.= ' FROM '.MAIN_DB_PREFIX .$InfoFieldList[0];
1037  if (!empty($InfoFieldList[4]))
1038  {
1039  // can use SELECT request
1040  if (strpos($InfoFieldList[4], '$SEL$')!==false) {
1041  $InfoFieldList[4]=str_replace('$SEL$','SELECT',$InfoFieldList[4]);
1042  }
1043 
1044  // current object id can be use into filter
1045  if (strpos($InfoFieldList[4], '$ID$')!==false && !empty($objectid)) {
1046  $InfoFieldList[4]=str_replace('$ID$',$objectid,$InfoFieldList[4]);
1047  } else {
1048  $InfoFieldList[4]=str_replace('$ID$','0',$InfoFieldList[4]);
1049  }
1050  //We have to join on extrafield table
1051  if (strpos($InfoFieldList[4], 'extra')!==false)
1052  {
1053  $sql.= ' as main, '.MAIN_DB_PREFIX .$InfoFieldList[0].'_extrafields as extra';
1054  $sqlwhere.= ' WHERE extra.fk_object=main.'.$InfoFieldList[2]. ' AND '.$InfoFieldList[4];
1055  }
1056  else
1057  {
1058  $sqlwhere.= ' WHERE '.$InfoFieldList[4];
1059  }
1060  }
1061  else
1062  {
1063  $sqlwhere.= ' WHERE 1=1';
1064  }
1065  // Some tables may have field, some other not. For the moment we disable it.
1066  if (in_array($InfoFieldList[0],array('tablewithentity')))
1067  {
1068  $sqlwhere.= ' AND entity = '.$conf->entity;
1069  }
1070  $sql.=$sqlwhere;
1071  //print $sql;
1072 
1073  $sql .= ' ORDER BY ' . implode(', ', $fields_label);
1074 
1075  dol_syslog(get_class($this).'::showInputField type=sellist', LOG_DEBUG);
1076  $resql = $this->db->query($sql);
1077  if ($resql)
1078  {
1079  $out.='<option value="0">&nbsp;</option>';
1080  $num = $this->db->num_rows($resql);
1081  $i = 0;
1082  while ($i < $num)
1083  {
1084  $labeltoshow='';
1085  $obj = $this->db->fetch_object($resql);
1086 
1087  // Several field into label (eq table:code|libelle:rowid)
1088  $notrans = false;
1089  $fields_label = explode('|',$InfoFieldList[1]);
1090  if (is_array($fields_label))
1091  {
1092  $notrans = true;
1093  foreach ($fields_label as $field_toshow)
1094  {
1095  $labeltoshow.= $obj->$field_toshow.' ';
1096  }
1097  }
1098  else
1099  {
1100  $labeltoshow=$obj->{$InfoFieldList[1]};
1101  }
1102  $labeltoshow=dol_trunc($labeltoshow,45);
1103 
1104  if ($value == $obj->rowid)
1105  {
1106  foreach ($fields_label as $field_toshow)
1107  {
1108  $translabel=$langs->trans($obj->$field_toshow);
1109  if ($translabel!=$obj->$field_toshow) {
1110  $labeltoshow=dol_trunc($translabel,18).' ';
1111  }else {
1112  $labeltoshow=dol_trunc($obj->$field_toshow,18).' ';
1113  }
1114  }
1115  $out.='<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
1116  }
1117  else
1118  {
1119  if (! $notrans)
1120  {
1121  $translabel=$langs->trans($obj->{$InfoFieldList[1]});
1122  if ($translabel!=$obj->{$InfoFieldList[1]}) {
1123  $labeltoshow=dol_trunc($translabel,18);
1124  }
1125  else {
1126  $labeltoshow=dol_trunc($obj->{$InfoFieldList[1]},18);
1127  }
1128  }
1129  if (empty($labeltoshow)) $labeltoshow='(not defined)';
1130  if ($value==$obj->rowid)
1131  {
1132  $out.='<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
1133  }
1134 
1135  if (!empty($InfoFieldList[3]) && $parentField)
1136  {
1137  $parent = $parentName.':'.$obj->{$parentField};
1138  }
1139 
1140  $out.='<option value="'.$obj->rowid.'"';
1141  $out.= ($value==$obj->rowid?' selected':'');
1142  $out.= (!empty($parent)?' parent="'.$parent.'"':'');
1143  $out.='>'.$labeltoshow.'</option>';
1144  }
1145 
1146  $i++;
1147  }
1148  $this->db->free($resql);
1149  }
1150  else {
1151  print 'Error in request '.$sql.' '.$this->db->lasterror().'. Check setup of extra parameters.<br>';
1152  }
1153  }
1154  $out.='</select>';
1155  }
1156  elseif ($type == 'checkbox')
1157  {
1158  $value_arr=explode(',',$value);
1159  $out=$form->multiselectarray($keyprefix.$key.$keysuffix, (empty($param['options'])?null:$param['options']), $value_arr, '', 0, '', 0, '100%');
1160  }
1161  elseif ($type == 'radio')
1162  {
1163  $out='';
1164  foreach ($param['options'] as $keyopt => $val)
1165  {
1166  $out.='<input class="flat '.$showsize.'" type="radio" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam?$moreparam:'');
1167  $out.=' value="'.$keyopt.'"';
1168  $out.=' id="'.$keyprefix.$key.$keysuffix.'_'.$keyopt.'"';
1169  $out.= ($value==$keyopt?'checked':'');
1170  $out.='/><label for="'.$keyprefix.$key.$keysuffix.'_'.$keyopt.'">'.$val.'</label><br>';
1171  }
1172  }
1173  elseif ($type == 'chkbxlst')
1174  {
1175  if (is_array($value)) {
1176  $value_arr = $value;
1177  }
1178  else {
1179  $value_arr = explode(',', $value);
1180  }
1181 
1182  if (is_array($param['options'])) {
1183  $param_list = array_keys($param['options']);
1184  $InfoFieldList = explode(":", $param_list[0]);
1185  $parentName='';
1186  $parentField='';
1187  // 0 : tableName
1188  // 1 : label field name
1189  // 2 : key fields name (if differ of rowid)
1190  // 3 : key field parent (for dependent lists)
1191  // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
1192  $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2] . ' as rowid');
1193 
1194  if (count($InfoFieldList) > 3 && ! empty($InfoFieldList[3])) {
1195  list ( $parentName, $parentField ) = explode('|', $InfoFieldList[3]);
1196  $keyList .= ', ' . $parentField;
1197  }
1198  if (count($InfoFieldList) > 4 && ! empty($InfoFieldList[4])) {
1199  if (strpos($InfoFieldList[4], 'extra.') !== false) {
1200  $keyList = 'main.' . $InfoFieldList[2] . ' as rowid';
1201  } else {
1202  $keyList = $InfoFieldList[2] . ' as rowid';
1203  }
1204  }
1205 
1206  $fields_label = explode('|', $InfoFieldList[1]);
1207  if (is_array($fields_label)) {
1208  $keyList .= ', ';
1209  $keyList .= implode(', ', $fields_label);
1210  }
1211 
1212  $sqlwhere = '';
1213  $sql = 'SELECT ' . $keyList;
1214  $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0];
1215  if (! empty($InfoFieldList[4])) {
1216 
1217  // can use SELECT request
1218  if (strpos($InfoFieldList[4], '$SEL$')!==false) {
1219  $InfoFieldList[4]=str_replace('$SEL$','SELECT',$InfoFieldList[4]);
1220  }
1221 
1222  // current object id can be use into filter
1223  if (strpos($InfoFieldList[4], '$ID$')!==false && !empty($objectid)) {
1224  $InfoFieldList[4]=str_replace('$ID$',$objectid,$InfoFieldList[4]);
1225  } else {
1226  $InfoFieldList[4]=str_replace('$ID$','0',$InfoFieldList[4]);
1227  }
1228 
1229  // We have to join on extrafield table
1230  if (strpos($InfoFieldList[4], 'extra') !== false) {
1231  $sql .= ' as main, ' . MAIN_DB_PREFIX . $InfoFieldList[0] . '_extrafields as extra';
1232  $sqlwhere .= ' WHERE extra.fk_object=main.' . $InfoFieldList[2] . ' AND ' . $InfoFieldList[4];
1233  } else {
1234  $sqlwhere .= ' WHERE ' . $InfoFieldList[4];
1235  }
1236  } else {
1237  $sqlwhere .= ' WHERE 1=1';
1238  }
1239  // Some tables may have field, some other not. For the moment we disable it.
1240  if (in_array($InfoFieldList[0], array ('tablewithentity')))
1241  {
1242  $sqlwhere .= ' AND entity = ' . $conf->entity;
1243  }
1244  // $sql.=preg_replace('/^ AND /','',$sqlwhere);
1245  // print $sql;
1246 
1247  $sql .= $sqlwhere;
1248  dol_syslog(get_class($this) . '::showInputField type=chkbxlst',LOG_DEBUG);
1249  $resql = $this->db->query($sql);
1250  if ($resql) {
1251  $num = $this->db->num_rows($resql);
1252  $i = 0;
1253 
1254  $data=array();
1255 
1256  while ( $i < $num ) {
1257  $labeltoshow = '';
1258  $obj = $this->db->fetch_object($resql);
1259 
1260  $notrans = false;
1261  // Several field into label (eq table:code|libelle:rowid)
1262  $fields_label = explode('|', $InfoFieldList[1]);
1263  if (is_array($fields_label)) {
1264  $notrans = true;
1265  foreach ( $fields_label as $field_toshow ) {
1266  $labeltoshow .= $obj->$field_toshow . ' ';
1267  }
1268  } else {
1269  $labeltoshow = $obj->{$InfoFieldList[1]};
1270  }
1271  $labeltoshow = dol_trunc($labeltoshow, 45);
1272 
1273  if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1274  foreach ( $fields_label as $field_toshow ) {
1275  $translabel = $langs->trans($obj->$field_toshow);
1276  if ($translabel != $obj->$field_toshow) {
1277  $labeltoshow = dol_trunc($translabel, 18) . ' ';
1278  } else {
1279  $labeltoshow = dol_trunc($obj->$field_toshow, 18) . ' ';
1280  }
1281  }
1282 
1283  $data[$obj->rowid]=$labeltoshow;
1284 
1285  } else {
1286  if (! $notrans) {
1287  $translabel = $langs->trans($obj->{$InfoFieldList[1]});
1288  if ($translabel != $obj->{$InfoFieldList[1]}) {
1289  $labeltoshow = dol_trunc($translabel, 18);
1290  } else {
1291  $labeltoshow = dol_trunc($obj->{$InfoFieldList[1]}, 18);
1292  }
1293  }
1294  if (empty($labeltoshow))
1295  $labeltoshow = '(not defined)';
1296 
1297  if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1298  $data[$obj->rowid]=$labeltoshow;
1299  }
1300 
1301  if (! empty($InfoFieldList[3]) && $parentField) {
1302  $parent = $parentName . ':' . $obj->{$parentField};
1303  }
1304 
1305  $data[$obj->rowid]=$labeltoshow;
1306  }
1307 
1308  $i ++;
1309  }
1310  $this->db->free($resql);
1311 
1312  $out=$form->multiselectarray($keyprefix.$key.$keysuffix, $data, $value_arr, '', 0, '', 0, '100%');
1313 
1314  } else {
1315  print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.<br>';
1316  }
1317  }
1318  }
1319  elseif ($type == 'link')
1320  {
1321  $param_list=array_keys($param['options']); // $param_list='ObjectName:classPath'
1322  $showempty=(($required && $default != '')?0:1);
1323  $out=$form->selectForForms($param_list[0], $keyprefix.$key.$keysuffix, $value, $showempty);
1324  }
1325  elseif ($type == 'password')
1326  {
1327  // If prefix is 'search_', field is used as a filter, we use a common text field.
1328  $out='<input type="'.($keyprefix=='search_'?'text':'password').'" class="flat '.$showsize.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam?$moreparam:'').'>';
1329  }
1330  if (!empty($hidden)) {
1331  $out='<input type="hidden" value="'.$value.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'"/>';
1332  }
1333  /* Add comments
1334  if ($type == 'date') $out.=' (YYYY-MM-DD)';
1335  elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)';
1336  */
1337  return $out;
1338  }
1339 
1340 
1349  function showOutputField($key,$value,$moreparam='')
1350  {
1351  global $conf,$langs;
1352 
1353  $elementtype=$this->attribute_elementtype[$key]; // seems not used
1354  $label=$this->attribute_label[$key];
1355  $type=$this->attribute_type[$key];
1356  $size=$this->attribute_size[$key];
1357  $default=$this->attribute_default[$key];
1358  $computed=$this->attribute_computed[$key];
1359  $unique=$this->attribute_unique[$key];
1360  $required=$this->attribute_required[$key];
1361  $param=$this->attribute_param[$key];
1362  $perms=$this->attribute_perms[$key];
1363  $langfile=$this->attribute_langfile[$key];
1364  $list=$this->attribute_list[$key];
1365  $hidden=(($list == 0) ? 1 : 0); // If zero, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller)
1366 
1367  if ($hidden) return ''; // This is a protection. If field is hidden, we should just not call this method.
1368 
1369  // If field is a computed field, value must become result of compute
1370  if ($computed)
1371  {
1372  // Make the eval of compute string
1373  //var_dump($computed);
1374  $value = dol_eval($computed, 1, 0);
1375  }
1376 
1377  $showsize=0;
1378  if ($type == 'date')
1379  {
1380  $showsize=10;
1381  $value=dol_print_date($value, 'day', 'tzuser');
1382  }
1383  elseif ($type == 'datetime')
1384  {
1385  $showsize=19;
1386  $value=dol_print_date($value, 'dayhour', 'tzuser');
1387  }
1388  elseif ($type == 'int')
1389  {
1390  $showsize=10;
1391  }
1392  elseif ($type == 'double')
1393  {
1394  if (!empty($value)) {
1395  $value=price($value);
1396  }
1397  }
1398  elseif ($type == 'boolean')
1399  {
1400  $checked='';
1401  if (!empty($value)) {
1402  $checked=' checked ';
1403  }
1404  $value='<input type="checkbox" '.$checked.' '.($moreparam?$moreparam:'').' readonly disabled>';
1405  }
1406  elseif ($type == 'mail')
1407  {
1408  $value=dol_print_email($value, 0, 0, 0, 64, 1, 1);
1409  }
1410  elseif ($type == 'url')
1411  {
1412  $value=dol_print_url($value,'_blank',32,1);
1413  }
1414  elseif ($type == 'phone')
1415  {
1416  $value=dol_print_phone($value, '', 0, 0, '', '&nbsp;', 1);
1417  }
1418  elseif ($type == 'price')
1419  {
1420  $value=price($value, 0, $langs, 0, 0, -1, $conf->currency);
1421  }
1422  elseif ($type == 'select')
1423  {
1424  $value=$param['options'][$value];
1425  }
1426  elseif ($type == 'sellist')
1427  {
1428  $param_list=array_keys($param['options']);
1429  $InfoFieldList = explode(":", $param_list[0]);
1430 
1431  $selectkey="rowid";
1432  $keyList='rowid';
1433 
1434  if (count($InfoFieldList)>=3)
1435  {
1436  $selectkey = $InfoFieldList[2];
1437  $keyList=$InfoFieldList[2].' as rowid';
1438  }
1439 
1440  $fields_label = explode('|',$InfoFieldList[1]);
1441  if(is_array($fields_label)) {
1442  $keyList .=', ';
1443  $keyList .= implode(', ', $fields_label);
1444  }
1445 
1446  $sql = 'SELECT '.$keyList;
1447  $sql.= ' FROM '.MAIN_DB_PREFIX .$InfoFieldList[0];
1448  if (strpos($InfoFieldList[4], 'extra')!==false)
1449  {
1450  $sql.= ' as main';
1451  }
1452  if ($selectkey=='rowid' && empty($value)) {
1453  $sql.= " WHERE ".$selectkey."=0";
1454  } elseif ($selectkey=='rowid') {
1455  $sql.= " WHERE ".$selectkey."=".$this->db->escape($value);
1456  }else {
1457  $sql.= " WHERE ".$selectkey."='".$this->db->escape($value)."'";
1458  }
1459 
1460  //$sql.= ' AND entity = '.$conf->entity;
1461 
1462  dol_syslog(get_class($this).':showOutputField:$type=sellist', LOG_DEBUG);
1463  $resql = $this->db->query($sql);
1464  if ($resql)
1465  {
1466  $value=''; // value was used, so now we reste it to use it to build final output
1467 
1468  $obj = $this->db->fetch_object($resql);
1469 
1470  // Several field into label (eq table:code|libelle:rowid)
1471  $fields_label = explode('|',$InfoFieldList[1]);
1472 
1473  if(is_array($fields_label) && count($fields_label)>1)
1474  {
1475  foreach ($fields_label as $field_toshow)
1476  {
1477  $translabel='';
1478  if (!empty($obj->$field_toshow)) {
1479  $translabel=$langs->trans($obj->$field_toshow);
1480  }
1481  if ($translabel!=$field_toshow) {
1482  $value.=dol_trunc($translabel,18).' ';
1483  }else {
1484  $value.=$obj->$field_toshow.' ';
1485  }
1486  }
1487  }
1488  else
1489  {
1490  $translabel='';
1491  if (!empty($obj->{$InfoFieldList[1]})) {
1492  $translabel=$langs->trans($obj->{$InfoFieldList[1]});
1493  }
1494  if ($translabel!=$obj->{$InfoFieldList[1]}) {
1495  $value=dol_trunc($translabel,18);
1496  }else {
1497  $value=$obj->{$InfoFieldList[1]};
1498  }
1499  }
1500  }
1501  else dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING);
1502  }
1503  elseif ($type == 'radio')
1504  {
1505  $value=$param['options'][$value];
1506  }
1507  elseif ($type == 'checkbox')
1508  {
1509  $value_arr=explode(',',$value);
1510  $value='';
1511  $toprint=array();
1512  if (is_array($value_arr))
1513  {
1514  foreach ($value_arr as $keyval=>$valueval) {
1515  $toprint[]='<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">'.$param['options'][$valueval].'</li>';
1516  }
1517  }
1518  $value='<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
1519  }
1520  elseif ($type == 'chkbxlst')
1521  {
1522  $value_arr = explode(',', $value);
1523 
1524  $param_list = array_keys($param['options']);
1525  $InfoFieldList = explode(":", $param_list[0]);
1526 
1527  $selectkey = "rowid";
1528  $keyList = 'rowid';
1529 
1530  if (count($InfoFieldList) >= 3) {
1531  $selectkey = $InfoFieldList[2];
1532  $keyList = $InfoFieldList[2] . ' as rowid';
1533  }
1534 
1535  $fields_label = explode('|', $InfoFieldList[1]);
1536  if (is_array($fields_label)) {
1537  $keyList .= ', ';
1538  $keyList .= implode(', ', $fields_label);
1539  }
1540 
1541  $sql = 'SELECT ' . $keyList;
1542  $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0];
1543  if (strpos($InfoFieldList[4], 'extra') !== false) {
1544  $sql .= ' as main';
1545  }
1546  // $sql.= " WHERE ".$selectkey."='".$this->db->escape($value)."'";
1547  // $sql.= ' AND entity = '.$conf->entity;
1548 
1549  dol_syslog(get_class($this) . ':showOutputField:$type=chkbxlst',LOG_DEBUG);
1550  $resql = $this->db->query($sql);
1551  if ($resql) {
1552  $value = ''; // value was used, so now we reste it to use it to build final output
1553  $toprint=array();
1554  while ( $obj = $this->db->fetch_object($resql) ) {
1555 
1556  // Several field into label (eq table:code|libelle:rowid)
1557  $fields_label = explode('|', $InfoFieldList[1]);
1558  if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1559  if (is_array($fields_label) && count($fields_label) > 1) {
1560  foreach ( $fields_label as $field_toshow ) {
1561  $translabel = '';
1562  if (! empty($obj->$field_toshow)) {
1563  $translabel = $langs->trans($obj->$field_toshow);
1564  }
1565  if ($translabel != $field_toshow) {
1566  $toprint[]='<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">'.dol_trunc($translabel, 18).'</li>';
1567  } else {
1568  $toprint[]='<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">'.$obj->$field_toshow.'</li>';
1569  }
1570  }
1571  } else {
1572  $translabel = '';
1573  if (! empty($obj->{$InfoFieldList[1]})) {
1574  $translabel = $langs->trans($obj->{$InfoFieldList[1]});
1575  }
1576  if ($translabel != $obj->{$InfoFieldList[1]}) {
1577  $toprint[]='<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">'.dol_trunc($translabel, 18).'</li>';
1578  } else {
1579  $toprint[]='<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">'.$obj->{$InfoFieldList[1]}.'</li>';
1580  }
1581  }
1582  }
1583  }
1584  $value='<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
1585 
1586  } else {
1587  dol_syslog(get_class($this) . '::showOutputField error ' . $this->db->lasterror(), LOG_WARNING);
1588  }
1589  }
1590  elseif ($type == 'link')
1591  {
1592  $out='';
1593  // only if something to display (perf)
1594  if ($value)
1595  {
1596  $param_list=array_keys($param['options']); // $param_list='ObjectName:classPath'
1597 
1598  $InfoFieldList = explode(":", $param_list[0]);
1599  $classname=$InfoFieldList[0];
1600  $classpath=$InfoFieldList[1];
1601  if (! empty($classpath))
1602  {
1603  dol_include_once($InfoFieldList[1]);
1604  if ($classname && class_exists($classname))
1605  {
1606  $object = new $classname($this->db);
1607  $object->fetch($value);
1608  $value=$object->getNomUrl(3);
1609  }
1610  }
1611  else
1612  {
1613  dol_syslog('Error bad setup of extrafield', LOG_WARNING);
1614  return 'Error bad setup of extrafield';
1615  }
1616  }
1617  }
1618  elseif ($type == 'text')
1619  {
1620  $value=dol_htmlentitiesbr($value);
1621  }
1622  elseif ($type == 'password')
1623  {
1624  $value=preg_replace('/./i','*',$value);
1625  }
1626  else
1627  {
1628  $showsize=round($size);
1629  if ($showsize > 48) $showsize=48;
1630  }
1631 
1632  //print $type.'-'.$size;
1633  $out=$value;
1634 
1635  return $out;
1636  }
1637 
1644  function getAlignFlag($key)
1645  {
1646  global $conf,$langs;
1647 
1648  $type=$this->attribute_type[$key];
1649 
1650  $align='';
1651 
1652  if ($type == 'date')
1653  {
1654  $align="center";
1655  }
1656  elseif ($type == 'datetime')
1657  {
1658  $align="center";
1659  }
1660  elseif ($type == 'int')
1661  {
1662  $align="right";
1663  }
1664  elseif ($type == 'double')
1665  {
1666  $align="right";
1667  }
1668  elseif ($type == 'boolean')
1669  {
1670  $align="center";
1671  }
1672  elseif ($type == 'radio')
1673  {
1674  $align="center";
1675  }
1676  elseif ($type == 'checkbox')
1677  {
1678  $align="center";
1679  }
1680 
1681  return $align;
1682  }
1683 
1690  function showSeparator($key)
1691  {
1692  $out = '<tr class="trextrafieldseparator"><td colspan="4"><strong>'.$this->attribute_label[$key].'</strong></td></tr>';
1693  return $out;
1694  }
1695 
1704  function setOptionalsFromPost($extralabels,&$object,$onlykey='')
1705  {
1706  global $_POST, $langs;
1707  $nofillrequired='';// For error when required field left blank
1708  $error_field_required = array();
1709 
1710  if (is_array($extralabels))
1711  {
1712  // Get extra fields
1713  foreach ($extralabels as $key => $value)
1714  {
1715  if (! empty($onlykey) && $key != $onlykey) continue;
1716 
1717  $key_type = $this->attribute_type[$key];
1718  if ($this->attribute_required[$key] && empty($_POST["options_".$key])) // Check if empty without GETPOST, value can be alpha, int, array, etc...
1719  {
1720  $nofillrequired++;
1721  $error_field_required[] = $value;
1722  }
1723 
1724  if (in_array($key_type,array('date')))
1725  {
1726  // Clean parameters
1727  // TODO GMT date in memory must be GMT so we should add gm=true in parameters
1728  $value_key=dol_mktime(0, 0, 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]);
1729  }
1730  elseif (in_array($key_type,array('datetime')))
1731  {
1732  // Clean parameters
1733  // TODO GMT date in memory must be GMT so we should add gm=true in parameters
1734  $value_key=dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]);
1735  }
1736  else if (in_array($key_type,array('checkbox','chkbxlst')))
1737  {
1738  $value_arr=GETPOST("options_".$key, 'array'); // check if an array
1739  if (!empty($value_arr)) {
1740  $value_key=implode($value_arr,',');
1741  }else {
1742  $value_key='';
1743  }
1744  }
1745  else if (in_array($key_type,array('price','double')))
1746  {
1747  $value_arr=GETPOST("options_".$key);
1748  $value_key=price2num($value_arr);
1749  }
1750  else
1751  {
1752  $value_key=GETPOST("options_".$key);
1753  }
1754  $object->array_options["options_".$key]=$value_key;
1755  }
1756 
1757  if ($nofillrequired) {
1758  $langs->load('errors');
1759  setEventMessages($langs->trans('ErrorFieldsRequired').' : '.implode(', ',$error_field_required), null, 'errors');
1760  return -1;
1761  }
1762  else {
1763  return 1;
1764  }
1765  }
1766  else {
1767  return 0;
1768  }
1769  }
1770 
1779  function getOptionalsFromPost($extralabels,$keyprefix='',$keysuffix='')
1780  {
1781  global $_POST;
1782 
1783  $array_options = array();
1784  if (is_array($extralabels))
1785  {
1786  // Get extra fields
1787  foreach ($extralabels as $key => $value)
1788  {
1789  $key_type = $this->attribute_type[$key];
1790 
1791  if (in_array($key_type,array('date','datetime')))
1792  {
1793  // Clean parameters
1794  $value_key=dol_mktime($_POST[$keysuffix."options_".$key.$keyprefix."hour"], $_POST[$keysuffix."options_".$key.$keyprefix."min"], 0, $_POST[$keysuffix."options_".$key.$keyprefix."month"], $_POST[$keysuffix."options_".$key.$keyprefix."day"], $_POST[$keysuffix."options_".$key.$keyprefix."year"]);
1795  }
1796  else if (in_array($key_type,array('checkbox', 'chkbxlst')))
1797  {
1798  $value_arr=GETPOST($keysuffix."options_".$key.$keyprefix);
1799  // Make sure we get an array even if there's only one checkbox
1800  $value_arr=(array) $value_arr;
1801  $value_key=implode(',', $value_arr);
1802  }
1803  else if (in_array($key_type,array('price','double')))
1804  {
1805  $value_arr=GETPOST($keysuffix."options_".$key.$keyprefix);
1806  $value_key=price2num($value_arr);
1807  }
1808  else
1809  {
1810  $value_key=GETPOST($keysuffix."options_".$key.$keyprefix);
1811  }
1812 
1813  $array_options[$keysuffix."options_".$key]=$value_key; // No keyprefix here. keyprefix is used only for read.
1814  }
1815 
1816  return $array_options;
1817  }
1818  else {
1819  return 0;
1820  }
1821  }
1822 }
create($attrname, $type='varchar', $length=255, $elementtype='member', $unique=0, $required=0, $default_value='', $param='', $perms='', $list=0, $computed='')
Add a new optional attribute.
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve')
Convert a html select field into an ajax combobox.
Definition: ajax.lib.php:392
update_label($attrname, $label, $type, $size, $elementtype, $unique=0, $required=0, $pos=0, $param='', $alwayseditable=0, $perms='', $list=0, $ishidden=0, $default='', $computed='', $entity='', $langfile='', $enabled='1')
Modify description of personalized attribute.
dol_eval($s, $returnvalue=0, $hideerrors=1)
Replace eval function to add more security.
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '...' if string larger than length.
showOutputField($key, $value, $moreparam='')
Return HTML string to put an output field into a page.
dol_print_url($url, $target='_blank', $max=32, $withpicto=0)
Show Url link.
getOptionalsFromPost($extralabels, $keyprefix='', $keysuffix='')
return array_options array of data of extrafields value of object sent by a search form ...
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm=false, $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
__construct($db)
Constructor.
showSeparator($key)
Return HTML string to print separator extrafield.
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
if(empty($reshook)) $form
View.
Definition: perms.php:103
setOptionalsFromPost($extralabels, &$object, $onlykey='')
Fill array_options property of object by extrafields value (using for data sent by forms) ...
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...
GETPOST($paramname, $check='none', $method=0, $filter=NULL, $options=NULL, $noreplace=0)
Return value of a param into GET or POST supervariable.
Class to manage standard extra fields.
Class to manage generation of HTML components Only common components must be here.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
delete_label($attrname, $elementtype='member')
Delete description of an optional attribute.
create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list=-1, $ishidden=0, $default='', $computed='', $entity='', $langfile='', $enabled='1')
Add description of a new optional attribute.
dol_now($mode='gmt')
Return date for now.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages...
dol_print_date($time, $format='', $tzoutput='tzserver', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
fetch_name_optionals_label($elementtype, $forceload=false)
Load array this->attributes, or old this->attribute_xxx like attribute_label, attribute_type, ...
print
Draft customers invoices.
Definition: index.php:91
update($attrname, $label, $type, $length, $elementtype, $unique=0, $required=0, $pos=0, $param='', $alwayseditable=0, $perms='', $list='', $ishidden=0, $default='', $computed='', $entity='', $langfile='', $enabled='1')
Modify type of a personalized attribute.
dol_print_email($email, $cid=0, $socid=0, $addlink=0, $max=64, $showinvalid=1, $withpicto=0)
Show EMail link.
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
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Return a prefix to use for this Dolibarr instance, for session/cookie names or email id...
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
Class to manage a WYSIWYG editor.
dol_print_phone($phone, $countrycode='', $cid=0, $socid=0, $addlink='', $separ="&nbsp;", $withpicto='', $titlealt='', $adddivfloat=0)
Format phone numbers according to country.
getAlignFlag($key)
Return tag to describe alignement to use for this extrafield.
showInputField($key, $value, $moreparam='', $keysuffix='', $keyprefix='', $showsize=0, $objectid=0)
Return HTML string to put an input field into a page Code very similar with showInputField of common ...
price2num($amount, $rounding='', $alreadysqlnb=0)
Function that return a number with universal decimal format (decimal separator is '...
addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param='', $alwayseditable=0, $perms='', $list=-1, $ishidden=0, $computed='', $entity='', $langfile='', $enabled='1')
Add a new extra field parameter.