Completed
Branch develop (bb7c03)
by
unknown
34:20
created

ExtraFields::create()   F

Complexity

Conditions 24
Paths 488

Size

Total Lines 68
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 24
eloc 51
nc 488
nop 11
dl 0
loc 68
rs 3.8116
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/* Copyright (C) 2002-2003  Rodolphe Quiedeville    <[email protected]>
3
 * Copyright (C) 2002-2003  Jean-Louis Bergamo      <[email protected]>
4
 * Copyright (C) 2004       Sebastien Di Cintio     <[email protected]>
5
 * Copyright (C) 2004       Benoit Mortier          <[email protected]>
6
 * Copyright (C) 2009-2012  Laurent Destailleur     <[email protected]>
7
 * Copyright (C) 2009-2012  Regis Houssin           <[email protected]>
8
 * Copyright (C) 2013       Florian Henry           <[email protected]>
9
 * Copyright (C) 2015       Charles-Fr BENKE        <[email protected]>
10
 * Copyright (C) 2016       Raphaël Doursenaud      <[email protected]>
11
 * Copyright (C) 2017       Nicolas ZABOURI         <[email protected]>
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
27
/**
28
 * 	\file 		htdocs/core/class/extrafields.class.php
29
 *	\ingroup    core
30
 *	\brief      File of class to manage extra fields
31
 */
32
33
34
/**
35
 *	Class to manage standard extra fields
36
 */
37
class ExtraFields
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
105
	/**
106
	 *	Constructor
107
	 *
108
	 *  @param		DoliDB		$db      Database handler
109
	*/
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
128
	/**
129
	 *  Add a new extra field parameter
130
	 *
131
	 *  @param	string			$attrname           Code of attribute
132
	 *  @param  string			$label              label of attribute
133
	 *  @param  int				$type               Type of attribute ('boolean', 'int', 'text', 'varchar', 'date', 'datehour','price','phone','mail','password','url','select','checkbox', ...)
134
	 *  @param  int				$pos                Position of attribute
135
	 *  @param  string			$size               Size/length of attribute
136
	 *  @param  string			$elementtype        Element type ('member', 'product', 'thirdparty', ...)
137
	 *  @param	int				$unique				Is field unique or not
138
	 *  @param	int				$required			Is field required or not
139
	 *  @param	string			$default_value		Defaulted value (In database. use the default_value feature for default value on screen. Example: '', '0', 'null', 'avalue')
140
	 *  @param  array|string	$param				Params for field (ex for select list : array('options' => array(value'=>'label of option')) )
141
	 *  @param  int				$alwayseditable		Is attribute always editable regardless of the document status
142
	 *  @param	string			$perms				Permission to check
143
	 *  @param	int				$list				Visibilty
144
	 *  @param	int				$ishidden			Deprecated. Use visibility instead.
145
	 *  @param  string  		$computed           Computed value
146
	 *  @param  string  		$entity    		 	Entity of extrafields
147
	 *  @param  string  		$langfile  		 	Language file
148
	 *  @return int      							<=0 if KO, >0 if OK
149
	 */
150
	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='')
151
	{
152
		if (empty($attrname)) return -1;
153
		if (empty($label)) return -1;
154
155
		if ($elementtype == 'thirdparty') $elementtype='societe';
156
		if ($elementtype == 'contact') $elementtype='socpeople';
157
158
		// Create field into database except for separator type which is not stored in database
159
		if ($type != 'separate')
160
		{
161
			$result=$this->create($attrname, $type, $size, $elementtype, $unique, $required, $default_value, $param, $perms, $list, $computed);
162
		}
163
		$err1=$this->errno;
164
		if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate')
0 ignored issues
show
Bug introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
165
		{
166
			// Add declaration of field into table
167
			$result2=$this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $ishidden, $default, $computed, $entity, $langfile);
0 ignored issues
show
Bug introduced by
The variable $default does not exist. Did you mean $default_value?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
168
			$err2=$this->errno;
169
			if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS'))
170
			{
171
				$this->error='';
172
				$this->errno=0;
173
				return 1;
174
			}
175
			else return -2;
176
		}
177
		else
178
		{
179
			return -1;
180
		}
181
	}
182
183
	/**
184
	 *	Add a new optional attribute.
185
	 *  This is a private method. For public method, use addExtraField.
186
	 *
187
	 *	@param	string	$attrname			code of attribute
188
	 *  @param	int		$type				Type of attribute ('boolean', 'int', 'text', 'varchar', 'date', 'datehour','price','phone','mail','password','url','select','checkbox', ...)
189
	 *  @param	string	$length				Size/length of attribute ('5', '24,8', ...)
190
	 *  @param  string	$elementtype        Element type ('member', 'product', 'thirdparty', 'contact', ...)
191
	 *  @param	int		$unique				Is field unique or not
192
	 *  @param	int		$required			Is field required or not
193
	 *  @param  string  $default_value		Default value for field (in database)
194
	 *  @param  array	$param				Params for field  (ex for select list : array('options'=>array('value'=>'label of option'))
195
	 *  @param	string	$perms				Permission
196
	 *	@param	int		$list				Into list view by default
197
	 *  @param  string  $computed           Computed value
198
	 *  @return int      	           		<=0 if KO, >0 if OK
199
	 */
200
	private function create($attrname, $type='varchar', $length=255, $elementtype='member', $unique=0, $required=0, $default_value='',$param='', $perms='', $list=0, $computed='')
201
	{
202
		if ($elementtype == 'thirdparty') $elementtype='societe';
203
		if ($elementtype == 'contact') $elementtype='socpeople';
204
205
		$table=$elementtype.'_extrafields';
206
		if ($elementtype == 'categorie') $table='categories_extrafields';
207
208
		if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9_]*$/",$attrname) && ! is_numeric($attrname))
209
		{
210
			if ($type=='boolean') {
211
				$typedb='int';
212
				$lengthdb='1';
213
			} elseif($type=='price') {
214
				$typedb='double';
215
				$lengthdb='24,8';
216
			} elseif($type=='phone') {
217
				$typedb='varchar';
218
				$lengthdb='20';
219
			} elseif($type=='mail') {
220
				$typedb='varchar';
221
				$lengthdb='128';
222
			} elseif($type=='url') {
223
				$typedb='varchar';
224
				$lengthdb='255';
225
			} elseif (($type=='select') || ($type=='sellist') || ($type=='radio') ||($type=='checkbox') ||($type=='chkbxlst')){
226
				$typedb='text';
227
				$lengthdb='';
228
			} elseif ($type=='link') {
229
				$typedb='int';
230
				$lengthdb='11';
231
			} elseif($type=='password') {
232
				$typedb='varchar';
233
				$lengthdb='50';
234
			} else {
235
				$typedb=$type;
236
				$lengthdb=$length;
237
				if ($type == 'varchar' && empty($lengthdb)) $lengthdb='255';
238
			}
239
			$field_desc = array(
240
			'type'=>$typedb,
241
			'value'=>$lengthdb,
242
			'null'=>($required?'NOT NULL':'NULL'),
243
			'default' => $default_value
244
			);
245
246
			$result=$this->db->DDLAddField(MAIN_DB_PREFIX.$table, $attrname, $field_desc);
247
			if ($result > 0)
248
			{
249
				if ($unique)
250
				{
251
					$sql="ALTER TABLE ".MAIN_DB_PREFIX.$table." ADD UNIQUE INDEX uk_".$table."_".$attrname." (".$attrname.")";
252
					$resql=$this->db->query($sql,1,'dml');
253
				}
254
				return 1;
255
			}
256
			else
257
			{
258
				$this->error=$this->db->lasterror();
259
				$this->errno=$this->db->lasterrno();
260
				return -1;
261
			}
262
		}
263
		else
264
		{
265
			return 0;
266
		}
267
	}
268
269
	/**
270
	 *	Add description of a new optional attribute
271
	 *
272
	 *	@param	string			$attrname		code of attribute
273
	 *	@param	string			$label			label of attribute
274
	 *  @param	int				$type			Type of attribute ('int', 'text', 'varchar', 'date', 'datehour', 'float')
275
	 *  @param	int				$pos			Position of attribute
276
	 *  @param	string			$size			Size/length of attribute ('5', '24,8', ...)
277
	 *  @param  string			$elementtype	Element type ('member', 'product', 'thirdparty', ...)
278
	 *  @param	int				$unique			Is field unique or not
279
	 *  @param	int				$required		Is field required or not
280
	 *  @param  array|string	$param			Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
281
	 *  @param  int				$alwayseditable	Is attribute always editable regardless of the document status
282
	 *  @param	string			$perms			Permission to check
283
	 *  @param	int				$list			Visibily
284
	 *  @param	int				$ishidden		Deprecated. Use visibility instead.
285
	 *  @param  string          $default        Default value (in database. use the default_value feature for default value on screen).
286
	 *  @param  string          $computed       Computed value
287
	 *  @param  string          $entity     	Entity of extrafields
288
	 *  @param	string			$langfile		Language file
289
	 *  @return	int								<=0 if KO, >0 if OK
290
	 */
291
	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='')
292
	{
293
		global $conf,$user;
294
295
		if ($elementtype == 'thirdparty') $elementtype='societe';
296
		if ($elementtype == 'contact') $elementtype='socpeople';
297
298
		// Clean parameters
299
		if (empty($pos)) $pos=0;
300
		if (empty($list)) $list=0;
301
302
		if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname) && ! is_numeric($attrname))
303
		{
304
			if(is_array($param) && count($param) > 0)
305
			{
306
				$params = $this->db->escape(serialize($param));
307
			}
308
			elseif (strlen($param) > 0)
309
			{
310
				$params = trim($param);
311
			}
312
			else
313
			{
314
				$params='';
315
			}
316
317
			$sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(";
318
			$sql.= " name,";
319
			$sql.= " label,";
320
			$sql.= " type,";
321
			$sql.= " pos,";
322
			$sql.= " size,";
323
			$sql.= " entity,";
324
			$sql.= " elementtype,";
325
			$sql.= " fieldunique,";
326
			$sql.= " fieldrequired,";
327
			$sql.= " param,";
328
			$sql.= " alwayseditable,";
329
			$sql.= " perms,";
330
			$sql.= " langs,";
331
			$sql.= " list,";
332
			$sql.= " fielddefault,";
333
			$sql.= " fieldcomputed,";
334
			$sql.= " fk_user_author,";
335
			$sql.= " fk_user_modif,";
336
			$sql.= " datec";
337
			$sql.= " )";
338
			$sql.= " VALUES('".$attrname."',";
339
			$sql.= " '".$this->db->escape($label)."',";
340
			$sql.= " '".$type."',";
341
			$sql.= " '".$pos."',";
342
			$sql.= " '".$size."',";
343
			$sql.= " ".($entity===''?$conf->entity:$entity).",";
344
			$sql.= " '".$elementtype."',";
345
			$sql.= " '".$unique."',";
346
			$sql.= " '".$required."',";
347
			$sql.= " '".$params."',";
348
			$sql.= " '".$alwayseditable."',";
349
			$sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null").",";
350
			$sql.= " ".($langfile?"'".$this->db->escape($langfile)."'":"null").",";
351
			$sql.= " ".$list.",";
352
			$sql.= " ".($default?"'".$this->db->escape($default)."'":"null").",";
353
			$sql.= " ".($computed?"'".$this->db->escape($computed)."'":"null").",";
354
			$sql .= " " . $user->id . ",";
355
			$sql .= " " . $user->id . ",";
356
			$sql .= "'" . $this->db->idate(dol_now()) . "'";
357
			$sql.=')';
358
359
			dol_syslog(get_class($this)."::create_label", LOG_DEBUG);
360
			if ($this->db->query($sql))
361
			{
362
				return 1;
363
			}
364
			else
365
			{
366
				$this->error=$this->db->lasterror();
367
				$this->errno=$this->db->lasterrno();
368
				return -1;
369
			}
370
		}
371
	}
372
373
	/**
374
	 *	Delete an optional attribute
375
	 *
376
	 *	@param	string	$attrname		Code of attribute to delete
377
	 *  @param  string	$elementtype    Element type ('member', 'product', 'thirdparty', 'contact', ...)
378
	 *  @return int              		< 0 if KO, 0 if nothing is done, 1 if OK
379
	 */
380
	function delete($attrname, $elementtype='member')
381
	{
382
		if ($elementtype == 'thirdparty') $elementtype='societe';
383
		if ($elementtype == 'contact') $elementtype='socpeople';
384
385
		$table=$elementtype.'_extrafields';
386
		if ($elementtype == 'categorie') $table='categories_extrafields';
387
388
		$error=0;
389
390
		if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
391
		{
392
			$result=$this->delete_label($attrname,$elementtype);
393
			if ($result < 0)
394
			{
395
			    $this->error=$this->db->lasterror();
396
			    $error++;
397
			}
398
399
			if (! $error)
400
			{
401
        		$sql = "SELECT COUNT(rowid) as nb";
402
        		$sql.= " FROM ".MAIN_DB_PREFIX."extrafields";
403
        		$sql.= " WHERE elementtype = '".$elementtype."'";
404
        		$sql.= " AND name = '".$attrname."'";
405
        		//$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
406
                $resql = $this->db->query($sql);
407
                if ($resql)
408
                {
409
                    $obj = $this->db->fetch_object($resql);
410
                    if ($obj->nb <= 0)
411
                    {
412
            			$result=$this->db->DDLDropField(MAIN_DB_PREFIX.$table,$attrname);	// This also drop the unique key
413
            			if ($result < 0)
414
            			{
415
            				$this->error=$this->db->lasterror();
416
            				$error++;
417
            			}
418
                    }
419
                }
420
			}
421
422
			return $result;
423
		}
424
		else
425
		{
426
			return 0;
427
		}
428
429
	}
430
431
	/**
432
	 *	Delete description of an optional attribute
433
	 *
434
	 *	@param	string	$attrname			Code of attribute to delete
435
	 *  @param  string	$elementtype        Element type ('member', 'product', 'thirdparty', ...)
436
	 *  @return int              			< 0 if KO, 0 if nothing is done, 1 if OK
437
	 */
438
	private function delete_label($attrname, $elementtype='member')
439
	{
440
		global $conf;
441
442
		if ($elementtype == 'thirdparty') $elementtype='societe';
443
		if ($elementtype == 'contact') $elementtype='socpeople';
444
445
		if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
446
		{
447
			$sql = "DELETE FROM ".MAIN_DB_PREFIX."extrafields";
448
			$sql.= " WHERE name = '".$attrname."'";
449
			$sql.= " AND entity IN  (0,".$conf->entity.')';
450
			$sql.= " AND elementtype = '".$elementtype."'";
451
452
			dol_syslog(get_class($this)."::delete_label", LOG_DEBUG);
453
			$resql=$this->db->query($sql);
454
			if ($resql)
455
			{
456
				return 1;
457
			}
458
			else
459
			{
460
				print dol_print_error($this->db);
461
				return -1;
462
			}
463
		}
464
		else
465
		{
466
			return 0;
467
		}
468
469
	}
470
471
	/**
472
	 * 	Modify type of a personalized attribute
473
	 *
474
	 *  @param	string	$attrname			Name of attribute
475
	 *  @param	string	$label				Label of attribute
476
	 *  @param	string	$type				Type of attribute ('boolean', 'int', 'text', 'varchar', 'date', 'datehour','price','phone','mail','password','url','select','checkbox', ...)
477
	 *  @param	int		$length				Length of attribute
478
	 *  @param  string	$elementtype        Element type ('member', 'product', 'thirdparty', 'contact', ...)
479
	 *  @param	int		$unique				Is field unique or not
480
	 *  @param	int		$required			Is field required or not
481
	 *  @param	int		$pos				Position of attribute
482
	 *  @param  array	$param				Params for field (ex for select list : array('options' => array(value'=>'label of option')) )
483
	 *  @param  int		$alwayseditable		Is attribute always editable regardless of the document status
484
	 *  @param	string	$perms				Permission to check
485
	 *  @param	int		$list				Visibility
486
	 *  @param	int		$ishidden			Deprecated. Use  visiblity instead.
487
	 *  @param  string  $default            Default value (in database. use the default_value feature for default value on screen).
488
	 *  @param  string  $computed           Computed value
489
	 *  @param  string  $entity	            Entity of extrafields
490
	 *  @param	string	$langfile			Language file
491
	 * 	@return	int							>0 if OK, <=0 if KO
492
	 */
493
	function update($attrname, $label, $type, $length, $elementtype, $unique=0, $required=0, $pos=0, $param='', $alwayseditable=0, $perms='', $list='', $ishidden=0, $default='', $computed='', $entity='', $langfile='')
494
	{
495
		if ($elementtype == 'thirdparty') $elementtype='societe';
496
		if ($elementtype == 'contact') $elementtype='socpeople';
497
498
		$table=$elementtype.'_extrafields';
499
		if ($elementtype == 'categorie') $table='categories_extrafields';
500
501
		if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
502
		{
503
			if ($type=='boolean') {
504
				$typedb='int';
505
				$lengthdb='1';
506
			} elseif($type=='price') {
507
				$typedb='double';
508
				$lengthdb='24,8';
509
			} elseif($type=='phone') {
510
				$typedb='varchar';
511
				$lengthdb='20';
512
			} elseif($type=='mail') {
513
				$typedb='varchar';
514
				$lengthdb='128';
515
			} elseif($type=='url') {
516
				$typedb='varchar';
517
				$lengthdb='255';
518
			} elseif (($type=='select') || ($type=='sellist') || ($type=='radio') || ($type=='checkbox') || ($type=='chkbxlst')) {
519
				$typedb='text';
520
				$lengthdb='';
521
			} elseif ($type=='link') {
522
				$typedb='int';
523
				$lengthdb='11';
524
			} elseif($type=='password') {
525
				$typedb='varchar';
526
				$lengthdb='50';
527
			} else {
528
				$typedb=$type;
529
				$lengthdb=$length;
530
			}
531
			$field_desc = array('type'=>$typedb, 'value'=>$lengthdb, 'null'=>($required?'NOT NULL':'NULL'), 'default'=>$default);
532
533
			if ($type != 'separate') // No table update when separate type
534
			{
535
				$result=$this->db->DDLUpdateField(MAIN_DB_PREFIX.$table, $attrname, $field_desc);
536
			}
537
			if ($result > 0 || $type == 'separate')
538
			{
539
				if ($label)
540
				{
541
					$result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms,$list,$ishidden,$default,$computed,$entity,$langfile);
542
				}
543
				if ($result > 0)
0 ignored issues
show
Bug introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
544
				{
545
					$sql='';
546
					if ($unique)
547
					{
548
						$sql="ALTER TABLE ".MAIN_DB_PREFIX.$table." ADD UNIQUE INDEX uk_".$table."_".$attrname." (".$attrname.")";
549
					}
550
					else
551
					{
552
						$sql="ALTER TABLE ".MAIN_DB_PREFIX.$table." DROP INDEX uk_".$table."_".$attrname;
553
					}
554
					dol_syslog(get_class($this).'::update', LOG_DEBUG);
555
					$resql=$this->db->query($sql,1,'dml');
556
					return 1;
557
				}
558
				else
559
				{
560
					$this->error=$this->db->lasterror();
561
					return -1;
562
				}
563
			}
564
			else
565
			{
566
				$this->error=$this->db->lasterror();
567
				return -1;
568
			}
569
		}
570
		else
571
		{
572
			return 0;
573
		}
574
575
	}
576
577
	/**
578
	 *  Modify description of personalized attribute
579
	 *
580
	 *  @param	string	$attrname			Name of attribute
581
	 *  @param	string	$label				Label of attribute
582
	 *  @param  string	$type               Type of attribute
583
	 *  @param  int		$size		        Length of attribute
584
	 *  @param  string	$elementtype		Element type ('member', 'product', 'thirdparty', ...)
585
	 *  @param	int		$unique				Is field unique or not
586
	 *  @param	int		$required			Is field required or not
587
	 *  @param	int		$pos				Position of attribute
588
	 *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
589
	 *  @param  int		$alwayseditable		Is attribute always editable regardless of the document status
590
	 *  @param	string	$perms				Permission to check
591
	 *  @param	int		$list				Visiblity
592
	 *  @param	int		$ishidden			Deprecated. Use visility instead.
593
	 *  @param  string  $default            Default value (in database. use the default_value feature for default value on screen).
594
	 *  @param  string  $computed           Computed value
595
	 *  @param  string  $entity     		Entity of extrafields
596
	 *  @param	string	$langfile			Language file
597
	 *  @return	int							<=0 if KO, >0 if OK
598
	 */
599
	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='')
600
	{
601
		global $conf, $user;
602
		dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$ishidden.", ".$default.", ".$computed.", ".$entity.", ".$langfile);
603
604
		// Clean parameters
605
		if ($elementtype == 'thirdparty') $elementtype='societe';
606
		if ($elementtype == 'contact') $elementtype='socpeople';
607
608
		if (empty($list)) $list=0;
609
610
		if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
611
		{
612
			$this->db->begin();
613
614
			if(is_array($param) && count($param) > 0)
615
			{
616
				$param = $this->db->escape(serialize($param));
617
			}
618
619
			$sql_del = "DELETE FROM ".MAIN_DB_PREFIX."extrafields";
620
			$sql_del.= " WHERE name = '".$attrname."'";
621
			$sql_del.= " AND entity = ".($entity===''?$conf->entity:$entity);
622
			$sql_del.= " AND elementtype = '".$elementtype."'";
623
624
			$resql1=$this->db->query($sql_del);
625
626
			$sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(";
627
			$sql.= " name,";		// This is code
628
			$sql.= " entity,";
629
			$sql.= " label,";
630
			$sql.= " type,";
631
			$sql.= " size,";
632
			$sql.= " elementtype,";
633
			$sql.= " fieldunique,";
634
			$sql.= " fieldrequired,";
635
			$sql.= " perms,";
636
			$sql.= " langs,";
637
			$sql.= " pos,";
638
			$sql.= " alwayseditable,";
639
			$sql.= " param,";
640
			$sql.= " list,";
641
			$sql.= " fielddefault,";
642
			$sql.= " fieldcomputed,";
643
			$sql.= " fk_user_author,";
644
			$sql.= " fk_user_modif,";
645
			$sql.= " datec";
646
			$sql.= ") VALUES (";
647
			$sql.= "'".$attrname."',";
648
			$sql.= " ".($entity===''?$conf->entity:$entity).",";
649
			$sql.= " '".$this->db->escape($label)."',";
650
			$sql.= " '".$type."',";
651
			$sql.= " '".$size."',";
652
			$sql.= " '".$elementtype."',";
653
			$sql.= " '".$unique."',";
654
			$sql.= " '".$required."',";
655
			$sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null").",";
656
			$sql.= " ".($langfile?"'".$this->db->escape($langfile)."'":"null").",";
657
			$sql.= " '".$pos."',";
658
			$sql.= " '".$alwayseditable."',";
659
			$sql.= " '".$param."',";
660
			$sql.= " ".$list.", ";
661
			$sql.= " ".(($default!='')?"'".$this->db->escape($default)."'":"null").",";
662
			$sql.= " ".($computed?"'".$this->db->escape($computed)."'":"null").",";
663
			$sql .= " " . $user->id . ",";
664
			$sql .= " " . $user->id . ",";
665
			$sql .= "'" . $this->db->idate(dol_now()) . "'";
666
			$sql.= ")";
667
668
			$resql2=$this->db->query($sql);
669
670
			if ($resql1 && $resql2)
671
			{
672
				$this->db->commit();
673
				return 1;
674
			}
675
			else
676
			{
677
				$this->db->rollback();
678
				print dol_print_error($this->db);
679
				return -1;
680
			}
681
		}
682
		else
683
		{
684
			return 0;
685
		}
686
687
	}
688
689
690
	/**
691
	 * 	Load array this->attributes, or old this->attribute_xxx like attribute_label, attribute_type, ...
692
	 *
693
	 * 	@param	string		$elementtype		Type of element ('adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...).
694
	 * 	@param	boolean		$forceload			Force load of extra fields whatever is option MAIN_EXTRAFIELDS_DISABLED. Deprecated. Should not be required.
695
	 * 	@return	array							Array of attributes keys+label for all extra fields.
696
	 */
697
	function fetch_name_optionals_label($elementtype,$forceload=false)
698
	{
699
		global $conf;
700
701
		if (empty($elementtype) ) return array();
702
703
		if ($elementtype == 'thirdparty') $elementtype='societe';
704
		if ($elementtype == 'contact') $elementtype='socpeople';
705
706
		$array_name_label=array();
707
708
		// To avoid conflicts with external modules. TODO Remove this.
709
		if (!$forceload && !empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) return $array_name_label;
710
711
		// 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.
712
		dol_syslog("fetch_name_optionals_label elementtype=".$elementtype);
713
714
		$sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,fielddefault,fieldcomputed";
715
		$sql .= ",entity";
716
		$sql.= " FROM ".MAIN_DB_PREFIX."extrafields";
717
		$sql.= " WHERE entity IN (0,".$conf->entity.")";
718
		if ($elementtype) $sql.= " AND elementtype = '".$elementtype."'";
719
		$sql.= " ORDER BY pos";
720
721
		$resql=$this->db->query($sql);
722
		if ($resql)
723
		{
724
			if ($this->db->num_rows($resql))
725
			{
726
				while ($tab = $this->db->fetch_object($resql))
727
				{
728
					// We can add this attribute to object. TODO Remove this and return $this->attributes[$elementtype]['label']
729
					if ($tab->type != 'separate')
730
					{
731
						$array_name_label[$tab->name]=$tab->label;
732
					}
733
734
					// Old usage
735
					$this->attribute_type[$tab->name]=$tab->type;
736
					$this->attribute_label[$tab->name]=$tab->label;
737
					$this->attribute_size[$tab->name]=$tab->size;
738
					$this->attribute_elementtype[$tab->name]=$tab->elementtype;
739
					$this->attribute_default[$tab->name]=$tab->fielddefault;
740
					$this->attribute_computed[$tab->name]=$tab->fieldcomputed;
741
					$this->attribute_unique[$tab->name]=$tab->fieldunique;
742
					$this->attribute_required[$tab->name]=$tab->fieldrequired;
743
					$this->attribute_param[$tab->name]=($tab->param ? unserialize($tab->param) : '');
744
					$this->attribute_pos[$tab->name]=$tab->pos;
745
					$this->attribute_alwayseditable[$tab->name]=$tab->alwayseditable;
746
					$this->attribute_perms[$tab->name]=(strlen($tab->perms) == 0 ? 1 : $tab->perms);
747
					$this->attribute_langfile[$tab->name]=$tab->langs;
748
					$this->attribute_list[$tab->name]=$tab->list;
749
					$this->attribute_entityid[$tab->name]=$tab->entity;
750
751
					// New usage
752
					$this->attributes[$tab->elementtype]['type'][$tab->name]=$tab->type;
753
					$this->attributes[$tab->elementtype]['label'][$tab->name]=$tab->label;
754
					$this->attributes[$tab->elementtype]['size'][$tab->name]=$tab->size;
755
					$this->attributes[$tab->elementtype]['elementtype'][$tab->name]=$tab->elementtype;
756
					$this->attributes[$tab->elementtype]['default'][$tab->name]=$tab->fielddefault;
757
					$this->attributes[$tab->elementtype]['computed'][$tab->name]=$tab->fieldcomputed;
758
					$this->attributes[$tab->elementtype]['unique'][$tab->name]=$tab->fieldunique;
759
					$this->attributes[$tab->elementtype]['required'][$tab->name]=$tab->fieldrequired;
760
					$this->attributes[$tab->elementtype]['param'][$tab->name]=($tab->param ? unserialize($tab->param) : '');
761
					$this->attributes[$tab->elementtype]['pos'][$tab->name]=$tab->pos;
762
					$this->attributes[$tab->elementtype]['alwayseditable'][$tab->name]=$tab->alwayseditable;
763
					$this->attributes[$tab->elementtype]['perms'][$tab->name]=(strlen($tab->perms) == 0 ? 1 : $tab->perms);
764
					$this->attributes[$tab->elementtype]['langfile'][$tab->name]=$tab->langs;
765
					$this->attributes[$tab->elementtype]['list'][$tab->name]=$tab->list;
766
					$this->attributes[$tab->elementtype]['entityid'][$tab->name]=$tab->entity;
767
768
					if (!empty($conf->multicompany->enabled))
769
					{
770
						$sql_entity_name='SELECT label FROM '.MAIN_DB_PREFIX.'entity WHERE rowid='.$tab->entity;
771
						$resql_entity_name=$this->db->query($sql_entity_name);
772
						if ($resql_entity_name)
773
						{
774
							if ($this->db->num_rows($resql_entity_name))
775
							{
776
								if ($obj = $this->db->fetch_object($resql_entity_name))
777
								{
778
									$this->attribute_entitylabel[$tab->name]=$obj->label;
779
									$this->attributes[$tab->elementtype]['entitylabel'][$tab->name]=$obj->label;
780
								}
781
							}
782
						}
783
					}
784
				}
785
			}
786
			if ($elementtype) $this->attributes[$elementtype]['loaded']=1;
787
		}
788
		else
789
		{
790
			$this->error=$this->db->lasterror();
791
			dol_syslog(get_class($this)."::fetch_name_optionals_label ".$this->error, LOG_ERR);
792
		}
793
794
		return $array_name_label;
795
	}
796
797
798
	/**
799
	 * Return HTML string to put an input field into a page
800
	 * Code very similar with showInputField of common object
801
	 *
802
	 * @param  string  $key            Key of attribute
803
	 * @param  string  $value          Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value)
804
	 * @param  string  $moreparam      To add more parametes on html input tag
805
	 * @param  string  $keysuffix      Prefix string to add after name and id of field (can be used to avoid duplicate names)
806
	 * @param  string  $keyprefix      Suffix string to add before name and id of field (can be used to avoid duplicate names)
807
	 * @param  mixed   $showsize       Value for css to define size. May also be a numeric.
808
	 * @param  int     $objectid       Current object id
809
	 * @return string
810
	 */
811
	function showInputField($key, $value, $moreparam='', $keysuffix='', $keyprefix='', $showsize=0, $objectid=0)
812
	{
813
		global $conf,$langs,$form;
814
815
		if (! is_object($form))
816
		{
817
			require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
818
			$form=new Form($this->db);
819
		}
820
821
		$out='';
822
823
		$keyprefix = $keyprefix.'options_';		// Because we work on extrafields
824
825
		$label=$this->attribute_label[$key];
826
		$type =$this->attribute_type[$key];
827
		$size =$this->attribute_size[$key];
828
		$elementtype=$this->attribute_elementtype[$key];	// Seems not used
829
		$default=$this->attribute_default[$key];
830
		$computed=$this->attribute_computed[$key];
831
		$unique=$this->attribute_unique[$key];
832
		$required=$this->attribute_required[$key];
833
		$param=$this->attribute_param[$key];
834
		$langfile=$this->attribute_langfile[$key];
835
		$list=$this->attribute_list[$key];
836
		$hidden=$this->attribute_hidden[$key];
837
838
		if ($computed)
839
		{
840
			if (! preg_match('/^search_/', $keyprefix)) return '<span class="opacitymedium">'.$langs->trans("AutomaticallyCalculated").'</span>';
841
			else return '';
842
		}
843
844
		if (empty($showsize))
845
		{
846
			if ($type == 'date')
847
			{
848
				//$showsize=10;
849
				$showsize = 'minwidth100imp';
850
			}
851
			elseif ($type == 'datetime')
852
			{
853
				//$showsize=19;
854
				$showsize = 'minwidth200imp';
855
			}
856
			elseif (in_array($type,array('int','integer','double','price')))
857
			{
858
				//$showsize=10;
859
				$showsize = 'maxwidth75';
860
			}
861
			elseif ($type == 'url')
862
			{
863
				$showsize='minwidth400';
864
			}
865
			elseif ($type == 'boolean')
866
			{
867
				$showsize='';
868
			}
869
			else
870
			{
871
				if (round($size) < 12)
872
				{
873
					$showsize = 'minwidth100';
874
				}
875
				else if (round($size) <= 48)
876
				{
877
					$showsize = 'minwidth200';
878
				}
879
				else
880
				{
881
					//$showsize=48;
882
					$showsize = 'minwidth400';
883
				}
884
			}
885
		}
886
887
		if (in_array($type,array('date','datetime')))
888
		{
889
			$tmp=explode(',',$size);
890
			$newsize=$tmp[0];
891
892
			$showtime = in_array($type,array('datetime')) ? 1 : 0;
893
894
			// Do not show current date when field not required (see select_date() method)
895
			if (!$required && $value == '') $value = '-1';
896
897
			// TODO Must also support $moreparam
898
			$out = $form->select_date($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 1, 0, 1);
899
		}
900
		elseif (in_array($type,array('int','integer')))
901
		{
902
			$tmp=explode(',',$size);
903
			$newsize=$tmp[0];
904
			$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:'').'>';
905
		}
906
		elseif (preg_match('/varchar/', $type))
907
		{
908
			$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:'').'>';
909
		}
910
		elseif (in_array($type, array('mail', 'phone', 'url')))
911
		{
912
			$out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam?$moreparam:'').'>';
913
		}
914
		elseif ($type == 'text')
915
		{
916
			if (! preg_match('/search_/', $keyprefix))		// If keyprefix is search_ or search_options_, we must just use a simple text field
917
			{
918
				require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
919
				$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%');
920
				$out=$doleditor->Create(1);
921
			}
922
			else
923
			{
924
				$out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam?$moreparam:'').'>';
925
			}
926
		}
927
		elseif ($type == 'boolean')
928
		{
929
			$checked='';
930
			if (!empty($value)) {
931
				$checked=' checked value="1" ';
932
			} else {
933
				$checked=' value="1" ';
934
			}
935
			$out='<input type="checkbox" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.$checked.' '.($moreparam?$moreparam:'').'>';
936
		}
937
		elseif ($type == 'price')
938
		{
939
			if (!empty($value)) {		// $value in memory is a php numeric, we format it into user number format.
940
				$value=price($value);
941
			}
942
			$out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam?$moreparam:'').'> '.$langs->getCurrencySymbol($conf->currency);
943
		}
944
		elseif ($type == 'double')
945
		{
946
			if (!empty($value)) {		// $value in memory is a php numeric, we format it into user number format.
947
				$value=price($value);
948
			}
949
			$out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam?$moreparam:'').'> ';
950
		}
951
		elseif ($type == 'select')
952
		{
953
			$out = '';
954
			if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->MAIN_EXTRAFIELDS_USE_SELECT2))
955
			{
956
				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
957
				$out.= ajax_combobox($keyprefix.$key.$keysuffix, array(), 0);
958
			}
959
960
			$out.='<select class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam?$moreparam:'').'>';
961
			$out.='<option value="0">&nbsp;</option>';
962
			foreach ($param['options'] as $key => $val)
963
			{
964
				if ((string) $key == '') continue;
965
				list($val, $parent) = explode('|', $val);
966
				$out.='<option value="'.$key.'"';
967
				$out.= (((string) $value == (string) $key)?' selected':'');
968
				$out.= (!empty($parent)?' parent="'.$parent.'"':'');
969
				$out.='>'.$val.'</option>';
970
			}
971
			$out.='</select>';
972
		}
973
		elseif ($type == 'sellist')
974
		{
975
			$out = '';
976
			if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->MAIN_EXTRAFIELDS_USE_SELECT2))
977
			{
978
				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
979
				$out.= ajax_combobox($keyprefix.$key.$keysuffix, array(), 0);
980
			}
981
982
			$out.='<select class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam?$moreparam:'').'>';
983
			if (is_array($param['options']))
984
			{
985
				$param_list=array_keys($param['options']);
986
				$InfoFieldList = explode(":", $param_list[0]);
987
				$parentName='';
988
				$parentField='';
989
				// 0 : tableName
990
				// 1 : label field name
991
				// 2 : key fields name (if differ of rowid)
992
				// 3 : key field parent (for dependent lists)
993
				// 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
994
				$keyList=(empty($InfoFieldList[2])?'rowid':$InfoFieldList[2].' as rowid');
995
996
997
				if (count($InfoFieldList) > 4 && ! empty($InfoFieldList[4]))
998
				{
999
					if (strpos($InfoFieldList[4], 'extra.') !== false)
1000
					{
1001
						$keyList='main.'.$InfoFieldList[2].' as rowid';
1002
					} else {
1003
						$keyList=$InfoFieldList[2].' as rowid';
1004
					}
1005
				}
1006
				if (count($InfoFieldList) > 3 && ! empty($InfoFieldList[3]))
1007
				{
1008
					list($parentName, $parentField) = explode('|', $InfoFieldList[3]);
1009
					$keyList.= ', '.$parentField;
1010
				}
1011
1012
				$fields_label = explode('|',$InfoFieldList[1]);
1013
				if (is_array($fields_label))
1014
				{
1015
					$keyList .=', ';
1016
					$keyList .= implode(', ', $fields_label);
1017
				}
1018
1019
				$sqlwhere='';
1020
				$sql = 'SELECT '.$keyList;
1021
				$sql.= ' FROM '.MAIN_DB_PREFIX .$InfoFieldList[0];
1022
				if (!empty($InfoFieldList[4]))
1023
				{
1024
					// can use SELECT request
1025
					if (strpos($InfoFieldList[4], '$SEL$')!==false) {
1026
						$InfoFieldList[4]=str_replace('$SEL$','SELECT',$InfoFieldList[4]);
1027
					}
1028
1029
					// current object id can be use into filter
1030
					if (strpos($InfoFieldList[4], '$ID$')!==false && !empty($objectid)) {
1031
						$InfoFieldList[4]=str_replace('$ID$',$objectid,$InfoFieldList[4]);
1032
					} else {
1033
						$InfoFieldList[4]=str_replace('$ID$','0',$InfoFieldList[4]);
1034
					}
1035
					//We have to join on extrafield table
1036
					if (strpos($InfoFieldList[4], 'extra')!==false)
1037
					{
1038
						$sql.= ' as main, '.MAIN_DB_PREFIX .$InfoFieldList[0].'_extrafields as extra';
1039
						$sqlwhere.= ' WHERE extra.fk_object=main.'.$InfoFieldList[2]. ' AND '.$InfoFieldList[4];
1040
					}
1041
					else
1042
					{
1043
						$sqlwhere.= ' WHERE '.$InfoFieldList[4];
1044
					}
1045
				}
1046
				else
1047
				{
1048
					$sqlwhere.= ' WHERE 1=1';
1049
				}
1050
				// Some tables may have field, some other not. For the moment we disable it.
1051
				if (in_array($InfoFieldList[0],array('tablewithentity')))
1052
				{
1053
					$sqlwhere.= ' AND entity = '.$conf->entity;
1054
				}
1055
				$sql.=$sqlwhere;
1056
				//print $sql;
1057
1058
				$sql .= ' ORDER BY ' . implode(', ', $fields_label);
1059
1060
				dol_syslog(get_class($this).'::showInputField type=sellist', LOG_DEBUG);
1061
				$resql = $this->db->query($sql);
1062
				if ($resql)
1063
				{
1064
					$out.='<option value="0">&nbsp;</option>';
1065
					$num = $this->db->num_rows($resql);
1066
					$i = 0;
1067
					while ($i < $num)
1068
					{
1069
						$labeltoshow='';
1070
						$obj = $this->db->fetch_object($resql);
1071
1072
						// Several field into label (eq table:code|libelle:rowid)
1073
						$notrans = false;
1074
						$fields_label = explode('|',$InfoFieldList[1]);
1075
						if (is_array($fields_label))
1076
						{
1077
							$notrans = true;
1078
							foreach ($fields_label as $field_toshow)
1079
							{
1080
								$labeltoshow.= $obj->$field_toshow.' ';
1081
							}
1082
						}
1083
						else
1084
						{
1085
							$labeltoshow=$obj->{$InfoFieldList[1]};
1086
						}
1087
						$labeltoshow=dol_trunc($labeltoshow,45);
1088
1089
						if ($value == $obj->rowid)
1090
						{
1091
							foreach ($fields_label as $field_toshow)
1092
							{
1093
								$translabel=$langs->trans($obj->$field_toshow);
1094
								if ($translabel!=$obj->$field_toshow) {
1095
									$labeltoshow=dol_trunc($translabel,18).' ';
1096
								}else {
1097
									$labeltoshow=dol_trunc($obj->$field_toshow,18).' ';
1098
								}
1099
							}
1100
							$out.='<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
1101
						}
1102
						else
1103
						{
1104
							if (! $notrans)
1105
							{
1106
								$translabel=$langs->trans($obj->{$InfoFieldList[1]});
1107
								if ($translabel!=$obj->{$InfoFieldList[1]}) {
1108
									$labeltoshow=dol_trunc($translabel,18);
1109
								}
1110
								else {
1111
									$labeltoshow=dol_trunc($obj->{$InfoFieldList[1]},18);
1112
								}
1113
							}
1114
							if (empty($labeltoshow)) $labeltoshow='(not defined)';
1115
							if ($value==$obj->rowid)
1116
							{
1117
								$out.='<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
1118
							}
1119
1120
							if (!empty($InfoFieldList[3]) && $parentField)
1121
							{
1122
								$parent = $parentName.':'.$obj->{$parentField};
1123
							}
1124
1125
							$out.='<option value="'.$obj->rowid.'"';
1126
							$out.= ($value==$obj->rowid?' selected':'');
1127
							$out.= (!empty($parent)?' parent="'.$parent.'"':'');
1128
							$out.='>'.$labeltoshow.'</option>';
1129
						}
1130
1131
						$i++;
1132
					}
1133
					$this->db->free($resql);
1134
				}
1135
				else {
1136
					print 'Error in request '.$sql.' '.$this->db->lasterror().'. Check setup of extra parameters.<br>';
1137
				}
1138
			}
1139
			$out.='</select>';
1140
		}
1141
		elseif ($type == 'checkbox')
1142
		{
1143
			$value_arr=explode(',',$value);
1144
			$out=$form->multiselectarray($keyprefix.$key.$keysuffix, (empty($param['options'])?null:$param['options']), $value_arr, '', 0, '', 0, '100%');
1145
		}
1146
		elseif ($type == 'radio')
1147
		{
1148
			$out='';
1149
			foreach ($param['options'] as $keyopt => $val)
1150
			{
1151
				$out.='<input class="flat '.$showsize.'" type="radio" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam?$moreparam:'');
1152
				$out.=' value="'.$keyopt.'"';
1153
				$out.=' id="'.$keyprefix.$key.$keysuffix.'_'.$keyopt.'"';
1154
				$out.= ($value==$keyopt?'checked':'');
1155
				$out.='/><label for="'.$keyprefix.$key.$keysuffix.'_'.$keyopt.'">'.$val.'</label><br>';
1156
			}
1157
		}
1158
		elseif ($type == 'chkbxlst')
1159
		{
1160
			if (is_array($value)) {
1161
				$value_arr = $value;
1162
			}
1163
			else {
1164
				$value_arr = explode(',', $value);
1165
			}
1166
1167
			if (is_array($param['options'])) {
1168
				$param_list = array_keys($param['options']);
1169
				$InfoFieldList = explode(":", $param_list[0]);
1170
				$parentName='';
1171
				$parentField='';
1172
				// 0 : tableName
1173
				// 1 : label field name
1174
				// 2 : key fields name (if differ of rowid)
1175
				// 3 : key field parent (for dependent lists)
1176
				// 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
1177
				$keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2] . ' as rowid');
1178
1179
				if (count($InfoFieldList) > 3 && ! empty($InfoFieldList[3])) {
1180
					list ( $parentName, $parentField ) = explode('|', $InfoFieldList[3]);
1181
					$keyList .= ', ' . $parentField;
1182
				}
1183
				if (count($InfoFieldList) > 4 && ! empty($InfoFieldList[4])) {
1184
					if (strpos($InfoFieldList[4], 'extra.') !== false) {
1185
						$keyList = 'main.' . $InfoFieldList[2] . ' as rowid';
1186
					} else {
1187
						$keyList = $InfoFieldList[2] . ' as rowid';
1188
					}
1189
				}
1190
1191
				$fields_label = explode('|', $InfoFieldList[1]);
1192
				if (is_array($fields_label)) {
1193
					$keyList .= ', ';
1194
					$keyList .= implode(', ', $fields_label);
1195
				}
1196
1197
				$sqlwhere = '';
1198
				$sql = 'SELECT ' . $keyList;
1199
				$sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0];
1200
				if (! empty($InfoFieldList[4])) {
1201
1202
					// can use SELECT request
1203
					if (strpos($InfoFieldList[4], '$SEL$')!==false) {
1204
						$InfoFieldList[4]=str_replace('$SEL$','SELECT',$InfoFieldList[4]);
1205
					}
1206
1207
					// current object id can be use into filter
1208
					if (strpos($InfoFieldList[4], '$ID$')!==false && !empty($objectid)) {
1209
						$InfoFieldList[4]=str_replace('$ID$',$objectid,$InfoFieldList[4]);
1210
					} else {
1211
						$InfoFieldList[4]=str_replace('$ID$','0',$InfoFieldList[4]);
1212
					}
1213
1214
					// We have to join on extrafield table
1215
					if (strpos($InfoFieldList[4], 'extra') !== false) {
1216
						$sql .= ' as main, ' . MAIN_DB_PREFIX . $InfoFieldList[0] . '_extrafields as extra';
1217
						$sqlwhere .= ' WHERE extra.fk_object=main.' . $InfoFieldList[2] . ' AND ' . $InfoFieldList[4];
1218
					} else {
1219
						$sqlwhere .= ' WHERE ' . $InfoFieldList[4];
1220
					}
1221
				} else {
1222
					$sqlwhere .= ' WHERE 1=1';
1223
				}
1224
				// Some tables may have field, some other not. For the moment we disable it.
1225
				if (in_array($InfoFieldList[0], array ('tablewithentity')))
1226
				{
1227
					$sqlwhere .= ' AND entity = ' . $conf->entity;
1228
				}
1229
				// $sql.=preg_replace('/^ AND /','',$sqlwhere);
1230
				// print $sql;
1231
1232
				$sql .= $sqlwhere;
1233
				dol_syslog(get_class($this) . '::showInputField type=chkbxlst',LOG_DEBUG);
1234
				$resql = $this->db->query($sql);
1235
				if ($resql) {
1236
					$num = $this->db->num_rows($resql);
1237
					$i = 0;
1238
1239
					$data=array();
1240
1241
					while ( $i < $num ) {
1242
						$labeltoshow = '';
1243
						$obj = $this->db->fetch_object($resql);
1244
1245
						$notrans = false;
1246
						// Several field into label (eq table:code|libelle:rowid)
1247
						$fields_label = explode('|', $InfoFieldList[1]);
1248
						if (is_array($fields_label)) {
1249
							$notrans = true;
1250
							foreach ( $fields_label as $field_toshow ) {
1251
								$labeltoshow .= $obj->$field_toshow . ' ';
1252
							}
1253
						} else {
1254
							$labeltoshow = $obj->{$InfoFieldList[1]};
1255
						}
1256
						$labeltoshow = dol_trunc($labeltoshow, 45);
1257
1258
						if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1259
							foreach ( $fields_label as $field_toshow ) {
1260
								$translabel = $langs->trans($obj->$field_toshow);
1261
								if ($translabel != $obj->$field_toshow) {
1262
									$labeltoshow = dol_trunc($translabel, 18) . ' ';
1263
								} else {
1264
									$labeltoshow = dol_trunc($obj->$field_toshow, 18) . ' ';
1265
								}
1266
							}
1267
1268
							$data[$obj->rowid]=$labeltoshow;
1269
1270
						} else {
1271
							if (! $notrans) {
1272
								$translabel = $langs->trans($obj->{$InfoFieldList[1]});
1273
								if ($translabel != $obj->{$InfoFieldList[1]}) {
1274
									$labeltoshow = dol_trunc($translabel, 18);
1275
								} else {
1276
									$labeltoshow = dol_trunc($obj->{$InfoFieldList[1]}, 18);
1277
								}
1278
							}
1279
							if (empty($labeltoshow))
1280
								$labeltoshow = '(not defined)';
1281
1282
								if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1283
									$data[$obj->rowid]=$labeltoshow;
1284
								}
1285
1286
								if (! empty($InfoFieldList[3]) && $parentField) {
1287
									$parent = $parentName . ':' . $obj->{$parentField};
1288
								}
1289
1290
								$data[$obj->rowid]=$labeltoshow;
1291
						}
1292
1293
						$i ++;
1294
					}
1295
					$this->db->free($resql);
1296
1297
					$out=$form->multiselectarray($keyprefix.$key.$keysuffix, $data, $value_arr, '', 0, '', 0, '100%');
1298
1299
				} else {
1300
					print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.<br>';
1301
				}
1302
			}
1303
		}
1304
		elseif ($type == 'link')
1305
		{
1306
			$param_list=array_keys($param['options']);				// $param_list='ObjectName:classPath'
1307
			$showempty=(($required && $default != '')?0:1);
1308
			$out=$form->selectForForms($param_list[0], $keyprefix.$key.$keysuffix, $value, $showempty);
1309
		}
1310
		elseif ($type == 'password')
1311
		{
1312
			// If prefix is 'search_', field is used as a filter, we use a common text field.
1313
			$out='<input type="'.($keyprefix=='search_'?'text':'password').'" class="flat '.$showsize.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam?$moreparam:'').'>';
1314
		}
1315
		if (!empty($hidden)) {
1316
			$out='<input type="hidden" value="'.$value.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'"/>';
1317
		}
1318
		/* Add comments
1319
		 if ($type == 'date') $out.=' (YYYY-MM-DD)';
1320
		 elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)';
1321
		 */
1322
		return $out;
1323
	}
1324
1325
1326
	/**
1327
	 * Return HTML string to put an output field into a page
1328
	 *
1329
	 * @param   string	$key            Key of attribute
1330
	 * @param   string	$value          Value to show
1331
	 * @param	string	$moreparam		To add more parameters on html input tag (only checkbox use html input for output rendering)
1332
	 * @return	string					Formated value
1333
	 */
1334
	function showOutputField($key,$value,$moreparam='')
1335
	{
1336
		global $conf,$langs;
1337
1338
		$elementtype=$this->attribute_elementtype[$key];	// seems not used
1339
		$label=$this->attribute_label[$key];
1340
		$type=$this->attribute_type[$key];
1341
		$size=$this->attribute_size[$key];
1342
		$default=$this->attribute_default[$key];
1343
		$computed=$this->attribute_computed[$key];
1344
		$unique=$this->attribute_unique[$key];
1345
		$required=$this->attribute_required[$key];
1346
		$param=$this->attribute_param[$key];
1347
		$perms=$this->attribute_perms[$key];
1348
		$langfile=$this->attribute_langfile[$key];
1349
		$list=$this->attribute_list[$key];
1350
		$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)
1351
1352
		if ($hidden) return '';		// This is a protection. If field is hidden, we should just not call this method.
1353
1354
		// If field is a computed field, value must become result of compute
1355
		if ($computed)
1356
		{
1357
		    // Make the eval of compute string
1358
		    //var_dump($computed);
1359
		    $value = dol_eval($computed, 1, 0);
1360
		}
1361
1362
		$showsize=0;
1363
		if ($type == 'date')
1364
		{
1365
			$showsize=10;
1366
			$value=dol_print_date($value, 'day', 'tzuser');
1367
		}
1368
		elseif ($type == 'datetime')
1369
		{
1370
			$showsize=19;
1371
			$value=dol_print_date($value, 'dayhour', 'tzuser');
1372
		}
1373
		elseif ($type == 'int')
1374
		{
1375
			$showsize=10;
1376
		}
1377
		elseif ($type == 'double')
1378
		{
1379
			if (!empty($value)) {
1380
				$value=price($value);
1381
			}
1382
		}
1383
		elseif ($type == 'boolean')
1384
		{
1385
			$checked='';
1386
			if (!empty($value)) {
1387
				$checked=' checked ';
1388
			}
1389
			$value='<input type="checkbox" '.$checked.' '.($moreparam?$moreparam:'').' readonly disabled>';
1390
		}
1391
		elseif ($type == 'mail')
1392
		{
1393
			$value=dol_print_email($value, 0, 0, 0, 64, 1, 1);
1394
		}
1395
		elseif ($type == 'url')
1396
		{
1397
			$value=dol_print_url($value,'_blank',32,1);
1398
		}
1399
		elseif ($type == 'phone')
1400
		{
1401
			$value=dol_print_phone($value, '', 0, 0, '', '&nbsp;', 1);
1402
		}
1403
		elseif ($type == 'price')
1404
		{
1405
			$value=price($value, 0, $langs, 0, 0, -1, $conf->currency);
1406
		}
1407
		elseif ($type == 'select')
1408
		{
1409
			$value=$param['options'][$value];
1410
		}
1411
		elseif ($type == 'sellist')
1412
		{
1413
			$param_list=array_keys($param['options']);
1414
			$InfoFieldList = explode(":", $param_list[0]);
1415
1416
			$selectkey="rowid";
1417
			$keyList='rowid';
1418
1419
			if (count($InfoFieldList)>=3)
1420
			{
1421
				$selectkey = $InfoFieldList[2];
1422
				$keyList=$InfoFieldList[2].' as rowid';
1423
			}
1424
1425
			$fields_label = explode('|',$InfoFieldList[1]);
1426
			if(is_array($fields_label)) {
1427
				$keyList .=', ';
1428
				$keyList .= implode(', ', $fields_label);
1429
			}
1430
1431
			$sql = 'SELECT '.$keyList;
1432
			$sql.= ' FROM '.MAIN_DB_PREFIX .$InfoFieldList[0];
1433
			if (strpos($InfoFieldList[4], 'extra')!==false)
1434
			{
1435
				$sql.= ' as main';
1436
			}
1437
			if ($selectkey=='rowid' && empty($value)) {
1438
				$sql.= " WHERE ".$selectkey."=0";
1439
			} elseif ($selectkey=='rowid') {
1440
				$sql.= " WHERE ".$selectkey."=".$this->db->escape($value);
1441
			}else {
1442
				$sql.= " WHERE ".$selectkey."='".$this->db->escape($value)."'";
1443
			}
1444
1445
			//$sql.= ' AND entity = '.$conf->entity;
1446
1447
			dol_syslog(get_class($this).':showOutputField:$type=sellist', LOG_DEBUG);
1448
			$resql = $this->db->query($sql);
1449
			if ($resql)
1450
			{
1451
				$value='';	// value was used, so now we reste it to use it to build final output
1452
1453
				$obj = $this->db->fetch_object($resql);
1454
1455
				// Several field into label (eq table:code|libelle:rowid)
1456
				$fields_label = explode('|',$InfoFieldList[1]);
1457
1458
				if(is_array($fields_label) && count($fields_label)>1)
1459
				{
1460
					foreach ($fields_label as $field_toshow)
1461
					{
1462
						$translabel='';
1463
						if (!empty($obj->$field_toshow)) {
1464
							$translabel=$langs->trans($obj->$field_toshow);
1465
						}
1466
						if ($translabel!=$field_toshow) {
1467
							$value.=dol_trunc($translabel,18).' ';
1468
						}else {
1469
							$value.=$obj->$field_toshow.' ';
1470
						}
1471
					}
1472
				}
1473
				else
1474
				{
1475
					$translabel='';
1476
					if (!empty($obj->{$InfoFieldList[1]})) {
1477
						$translabel=$langs->trans($obj->{$InfoFieldList[1]});
1478
					}
1479
					if ($translabel!=$obj->{$InfoFieldList[1]}) {
1480
						$value=dol_trunc($translabel,18);
1481
					}else {
1482
						$value=$obj->{$InfoFieldList[1]};
1483
					}
1484
				}
1485
			}
1486
			else dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING);
1487
		}
1488
		elseif ($type == 'radio')
1489
		{
1490
			$value=$param['options'][$value];
1491
		}
1492
		elseif ($type == 'checkbox')
1493
		{
1494
			$value_arr=explode(',',$value);
1495
			$value='';
1496
			$toprint=array();
1497
			if (is_array($value_arr))
1498
			{
1499
				foreach ($value_arr as $keyval=>$valueval) {
1500
					$toprint[]='<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">'.$param['options'][$valueval].'</li>';
1501
				}
1502
			}
1503
			$value='<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
1504
		}
1505
		elseif ($type == 'chkbxlst')
1506
		{
1507
			$value_arr = explode(',', $value);
1508
1509
			$param_list = array_keys($param['options']);
1510
			$InfoFieldList = explode(":", $param_list[0]);
1511
1512
			$selectkey = "rowid";
1513
			$keyList = 'rowid';
1514
1515
			if (count($InfoFieldList) >= 3) {
1516
				$selectkey = $InfoFieldList[2];
1517
				$keyList = $InfoFieldList[2] . ' as rowid';
1518
			}
1519
1520
			$fields_label = explode('|', $InfoFieldList[1]);
1521
			if (is_array($fields_label)) {
1522
				$keyList .= ', ';
1523
				$keyList .= implode(', ', $fields_label);
1524
			}
1525
1526
			$sql = 'SELECT ' . $keyList;
1527
			$sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0];
1528
			if (strpos($InfoFieldList[4], 'extra') !== false) {
1529
				$sql .= ' as main';
1530
			}
1531
			// $sql.= " WHERE ".$selectkey."='".$this->db->escape($value)."'";
1532
			// $sql.= ' AND entity = '.$conf->entity;
1533
1534
			dol_syslog(get_class($this) . ':showOutputField:$type=chkbxlst',LOG_DEBUG);
1535
			$resql = $this->db->query($sql);
1536
			if ($resql) {
1537
				$value = ''; // value was used, so now we reste it to use it to build final output
1538
				$toprint=array();
1539
				while ( $obj = $this->db->fetch_object($resql) ) {
1540
1541
					// Several field into label (eq table:code|libelle:rowid)
1542
					$fields_label = explode('|', $InfoFieldList[1]);
1543
					if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1544
						if (is_array($fields_label) && count($fields_label) > 1) {
1545
							foreach ( $fields_label as $field_toshow ) {
1546
								$translabel = '';
1547
								if (! empty($obj->$field_toshow)) {
1548
									$translabel = $langs->trans($obj->$field_toshow);
1549
								}
1550
								if ($translabel != $field_toshow) {
1551
									$toprint[]='<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">'.dol_trunc($translabel, 18).'</li>';
1552
								} else {
1553
									$toprint[]='<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">'.$obj->$field_toshow.'</li>';
1554
								}
1555
							}
1556
						} else {
1557
							$translabel = '';
1558
							if (! empty($obj->{$InfoFieldList[1]})) {
1559
								$translabel = $langs->trans($obj->{$InfoFieldList[1]});
1560
							}
1561
							if ($translabel != $obj->{$InfoFieldList[1]}) {
1562
								$toprint[]='<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">'.dol_trunc($translabel, 18).'</li>';
1563
							} else {
1564
								$toprint[]='<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">'.$obj->{$InfoFieldList[1]}.'</li>';
1565
							}
1566
						}
1567
					}
1568
				}
1569
				$value='<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
1570
1571
			} else {
1572
				dol_syslog(get_class($this) . '::showOutputField error ' . $this->db->lasterror(), LOG_WARNING);
1573
			}
1574
		}
1575
		elseif ($type == 'link')
1576
		{
1577
			$out='';
1578
			// only if something to display (perf)
1579
			if ($value)
1580
			{
1581
				$param_list=array_keys($param['options']);				// $param_list='ObjectName:classPath'
1582
1583
				$InfoFieldList = explode(":", $param_list[0]);
1584
				$classname=$InfoFieldList[0];
1585
				$classpath=$InfoFieldList[1];
1586
				if (! empty($classpath))
1587
				{
1588
					dol_include_once($InfoFieldList[1]);
1589
					if ($classname && class_exists($classname))
1590
					{
1591
						$object = new $classname($this->db);
1592
						$object->fetch($value);
1593
						$value=$object->getNomUrl(3);
1594
					}
1595
				}
1596
				else
1597
				{
1598
					dol_syslog('Error bad setup of extrafield', LOG_WARNING);
1599
					return 'Error bad setup of extrafield';
1600
				}
1601
			}
1602
		}
1603
		elseif ($type == 'text')
1604
		{
1605
			$value=dol_htmlentitiesbr($value);
1606
		}
1607
		elseif ($type == 'password')
1608
		{
1609
			$value=preg_replace('/./i','*',$value);
1610
		}
1611
		else
1612
		{
1613
			$showsize=round($size);
1614
			if ($showsize > 48) $showsize=48;
1615
		}
1616
1617
		//print $type.'-'.$size;
1618
		$out=$value;
1619
1620
		return $out;
1621
	}
1622
1623
	/**
1624
	 * Return tag to describe alignement to use for this extrafield
1625
	 *
1626
	 * @param   string	$key            Key of attribute
1627
	 * @return	string					Formated value
1628
	 */
1629
	function getAlignFlag($key)
1630
	{
1631
		global $conf,$langs;
1632
1633
		$type=$this->attribute_type[$key];
1634
1635
		$align='';
1636
1637
		if ($type == 'date')
1638
		{
1639
			$align="center";
1640
		}
1641
		elseif ($type == 'datetime')
1642
		{
1643
			$align="center";
1644
		}
1645
		elseif ($type == 'int')
1646
		{
1647
			$align="right";
1648
		}
1649
		elseif ($type == 'double')
1650
		{
1651
			$align="right";
1652
		}
1653
		elseif ($type == 'boolean')
1654
		{
1655
			$align="center";
1656
		}
1657
		elseif ($type == 'radio')
1658
		{
1659
			$align="center";
1660
		}
1661
		elseif ($type == 'checkbox')
1662
		{
1663
			$align="center";
1664
		}
1665
1666
		return $align;
1667
	}
1668
1669
	/**
1670
	 * Return HTML string to print separator extrafield
1671
	 *
1672
	 * @param   string	$key            Key of attribute
1673
	 * @return string
1674
	 */
1675
	function showSeparator($key)
1676
	{
1677
		$out = '<tr class="trextrafieldseparator"><td colspan="4"><strong>'.$this->attribute_label[$key].'</strong></td></tr>';
1678
		return $out;
1679
	}
1680
1681
	/**
1682
	 * Fill array_options property of object by extrafields value (using for data sent by forms)
1683
	 *
1684
	 * @param   array	$extralabels    $array of extrafields
1685
	 * @param   object	$object         Object
1686
	 * @param	string	$onlykey		Only following key is filled. When we make update of only one extrafield ($action = 'update_extras'), calling page must must set this to avoid to have other extrafields being reset.
1687
	 * @return	int						1 if array_options set, 0 if no value, -1 if error (field required missing for example)
1688
	 */
1689
	function setOptionalsFromPost($extralabels,&$object,$onlykey='')
1690
	{
1691
		global $_POST, $langs;
1692
		$nofillrequired='';// For error when required field left blank
1693
		$error_field_required = array();
1694
1695
		if (is_array($extralabels))
1696
		{
1697
			// Get extra fields
1698
			foreach ($extralabels as $key => $value)
1699
			{
1700
				if (! empty($onlykey) && $key != $onlykey) continue;
1701
1702
				$key_type = $this->attribute_type[$key];
1703
				if ($this->attribute_required[$key] && empty($_POST["options_".$key])) // Check if empty without GETPOST, value can be alpha, int, array, etc...
1704
				{
1705
					$nofillrequired++;
1706
					$error_field_required[] = $value;
1707
				}
1708
1709
				if (in_array($key_type,array('date','datetime')))
1710
				{
1711
					// Clean parameters
1712
					$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"]);
1713
				}
1714
				else if (in_array($key_type,array('checkbox','chkbxlst')))
1715
				{
1716
					$value_arr=GETPOST("options_".$key, 'array'); // check if an array
1717
					if (!empty($value_arr)) {
1718
						$value_key=implode($value_arr,',');
1719
					}else {
1720
						$value_key='';
1721
					}
1722
				}
1723
				else if (in_array($key_type,array('price','double')))
1724
				{
1725
					$value_arr=GETPOST("options_".$key);
1726
					$value_key=price2num($value_arr);
1727
				}
1728
				else
1729
				{
1730
					$value_key=GETPOST("options_".$key);
1731
				}
1732
				$object->array_options["options_".$key]=$value_key;
1733
			}
1734
1735
			if ($nofillrequired) {
1736
				$langs->load('errors');
1737
				setEventMessages($langs->trans('ErrorFieldsRequired').' : '.implode(', ',$error_field_required), null, 'errors');
1738
				return -1;
1739
			}
1740
			else {
1741
				return 1;
1742
			}
1743
		}
1744
		else {
1745
			return 0;
1746
		}
1747
	}
1748
1749
	/**
1750
	 * return array_options array for object by extrafields value (using for data send by forms)
1751
	 *
1752
	 * @param  array   $extralabels    $array of extrafields
1753
	 * @param  string  $keyprefix      Prefix string to add into name and id of field (can be used to avoid duplicate names)
1754
	 * @param  string  $keysuffix      Suffix string to add into name and id of field (can be used to avoid duplicate names)
1755
	 * @return int                     1 if array_options set / 0 if no value
1756
	 */
1757
	function getOptionalsFromPost($extralabels,$keyprefix='',$keysuffix='')
1758
	{
1759
		global $_POST;
1760
1761
		$array_options = array();
1762
		if (is_array($extralabels))
1763
		{
1764
			// Get extra fields
1765
			foreach ($extralabels as $key => $value)
1766
			{
1767
				$key_type = $this->attribute_type[$key];
1768
1769
				if (in_array($key_type,array('date','datetime')))
1770
				{
1771
					// Clean parameters
1772
					$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"]);
1773
				}
1774
				else if (in_array($key_type,array('checkbox', 'chkbxlst')))
1775
				{
1776
					$value_arr=GETPOST($keysuffix."options_".$key.$keyprefix);
1777
					// Make sure we get an array even if there's only one checkbox
1778
					$value_arr=(array) $value_arr;
1779
					$value_key=implode(',', $value_arr);
1780
				}
1781
				else if (in_array($key_type,array('price','double')))
1782
				{
1783
					$value_arr=GETPOST($keysuffix."options_".$key.$keyprefix);
1784
					$value_key=price2num($value_arr);
1785
				}
1786
				else
1787
				{
1788
					$value_key=GETPOST($keysuffix."options_".$key.$keyprefix);
1789
				}
1790
1791
				$array_options[$keysuffix."options_".$key]=$value_key;	// No keyprefix here. keyprefix is used only for read.
1792
			}
1793
1794
			return $array_options;
1795
		}
1796
		else {
1797
			return 0;
1798
		}
1799
	}
1800
}
1801