Passed
Push — master ( 3cffbe...0f9140 )
by Alxarafe
23:50
created

AlExtraFields::create_label()   F

Complexity

Conditions 24
Paths > 20000

Size

Total Lines 84
Code Lines 73

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 24
eloc 73
nop 18
dl 0
loc 84
rs 0
c 0
b 0
f 0
nc 393344

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
 * Copyright (C) 2018       Frédéric France         <[email protected]>
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 3 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26
 */
27
28
/**
29
 * 	\file 		htdocs/core/class/extrafields.class.php
30
 * 	\ingroup    core
31
 * 	\brief      File of class to manage extra fields
32
 */
33
namespace Alixar\Base;
34
35
use Alxarafe\Helpers\Config;
36
use Alixar\Helpers\AlDolUtils;
37
use Alixar\Helpers\Globals;
38
39
/**
40
 * 	Class to manage standard extra fields
41
 */
42
class AlExtraFields
43
{
44
45
    /**
46
     * @var DoliDB Database handler.
0 ignored issues
show
Bug introduced by
The type Alixar\Base\DoliDB was not found. Did you mean DoliDB? If so, make sure to prefix the type with \.
Loading history...
47
     */
48
    // public $db;
49
    // type of element (for what object is the extrafield)
50
    // @deprecated
51
    var $attribute_elementtype;
52
    // Array with type of the extra field
53
    // @deprecated
54
    var $attribute_type;
55
    // Array with label of extra field
56
    // @deprecated
57
    var $attribute_label;
58
    // Array with size of extra field
59
    // @deprecated
60
    var $attribute_size;
61
    // array with list of possible values for some types of extra fields
62
    // @deprecated
63
    var $attribute_choice;
64
    // Array to store compute formula for computed fields
65
    // @deprecated
66
    var $attribute_computed;
67
    // Array to store default value
68
    // @deprecated
69
    var $attribute_default;
70
    // Array to store if attribute is unique or not
71
    // @deprecated
72
    var $attribute_unique;
73
    // Array to store if attribute is required or not
74
    // @deprecated
75
    var $attribute_required;
76
    // Array to store parameters of attribute (used in select type)
77
    // @deprecated
78
    var $attribute_param;
79
    // Array to store position of attribute
80
    // @deprecated
81
    var $attribute_pos;
82
    // Array to store if attribute is editable regardless of the document status
83
    // @deprecated
84
    var $attribute_alwayseditable;
85
    // Array to store permission to check
86
    // @deprecated
87
    var $attribute_perms;
88
    // Array to store language file to translate label of values
89
    // @deprecated
90
    var $attribute_langfile;
91
    // Array to store if field is visible by default on list
92
    // @deprecated
93
    var $attribute_list;
94
    // New array to store extrafields definition
95
    var $attributes;
96
97
    /**
98
     * @var string Error code (or message)
99
     */
100
    public $error = '';
101
    var $errno;
102
    public static $type2label = array(
103
        'varchar' => 'String',
104
        'text' => 'TextLong',
105
        'html' => 'HtmlText',
106
        'int' => 'Int',
107
        'double' => 'Float',
108
        'date' => 'Date',
109
        'datetime' => 'DateAndTime',
110
        'boolean' => 'Boolean',
111
        'price' => 'ExtrafieldPrice',
112
        'phone' => 'ExtrafieldPhone',
113
        'mail' => 'ExtrafieldMail',
114
        'url' => 'ExtrafieldUrl',
115
        'password' => 'ExtrafieldPassword',
116
        'select' => 'ExtrafieldSelect',
117
        'sellist' => 'ExtrafieldSelectList',
118
        'radio' => 'ExtrafieldRadio',
119
        'checkbox' => 'ExtrafieldCheckBox',
120
        'chkbxlst' => 'ExtrafieldCheckBoxFromList',
121
        'link' => 'ExtrafieldLink',
122
        'separate' => 'ExtrafieldSeparator',
123
    );
124
125
    /**
126
     * 	Constructor
127
     *
128
     *  @param		DoliDB		$db      Database handler
129
     */
130
    function __construct()
131
    {
132
        // Config::$dbEngine = $db;
133
        $this->error = array();
0 ignored issues
show
Documentation Bug introduced by
It seems like array() of type array is incompatible with the declared type string of property $error.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
134
        $this->attributes = array();
135
136
        // For old usage
137
        $this->attribute_elementtype = array();
0 ignored issues
show
Documentation Bug introduced by
It seems like array() of type array is incompatible with the declared type Alixar\Base\DoliDB of property $attribute_elementtype.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
138
        $this->attribute_type = array();
139
        $this->attribute_label = array();
140
        $this->attribute_size = array();
141
        $this->attribute_computed = array();
142
        $this->attribute_default = array();
143
        $this->attribute_unique = array();
144
        $this->attribute_required = array();
145
        $this->attribute_perms = array();
146
        $this->attribute_langfile = array();
147
        $this->attribute_list = array();
148
    }
149
150
    /**
151
     *  Add a new extra field parameter
152
     *
153
     *  @param	string			$attrname           Code of attribute
154
     *  @param  string			$label              label of attribute
155
     *  @param  int				$type               Type of attribute ('boolean','int','varchar','text','html','date','datehour','price','phone','mail','password','url','select','checkbox','separate',...)
156
     *  @param  int				$pos                Position of attribute
157
     *  @param  string			$size               Size/length of attribute
158
     *  @param  string			$elementtype        Element type. Same value than object->table_element (Example 'member', 'product', 'thirdparty', ...)
159
     *  @param	int				$unique				Is field unique or not
160
     *  @param	int				$required			Is field required or not
161
     *  @param	string			$default_value		Defaulted value (In database. use the default_value feature for default value on screen. Example: '', '0', 'null', 'avalue')
162
     *  @param  array|string	$param				Params for field (ex for select list : array('options' => array(value'=>'label of option')) )
163
     *  @param  int				$alwayseditable		Is attribute always editable regardless of the document status
164
     *  @param	string			$perms				Permission to check
165
     *  @param	string			$list				Visibilty ('0'=never visible, '1'=visible on list+forms, '2'=list only, '3'=form only or 'eval string')
166
     *  @param	string			$help				Text with help tooltip
167
     *  @param  string  		$computed           Computed value
168
     *  @param  string  		$entity    		 	Entity of extrafields (for multicompany modules)
169
     *  @param  string  		$langfile  		 	Language file
170
     *  @param  string  		$enabled  		 	Condition to have the field enabled or not
171
     *  @return int      							<=0 if KO, >0 if OK
172
     */
173
    function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique = 0, $required = 0, $default_value = '', $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $computed = '', $entity = '', $langfile = '', $enabled = '1')
174
    {
175
        if (empty($attrname))
176
            return -1;
177
        if (empty($label))
178
            return -1;
179
180
        if ($elementtype == 'thirdparty')
181
            $elementtype = 'societe';
182
        if ($elementtype == 'contact')
183
            $elementtype = 'socpeople';
184
185
        // Create field into database except for separator type which is not stored in database
186
        if ($type != 'separate') {
187
            $result = $this->create($attrname, $type, $size, $elementtype, $unique, $required, $default_value, $param, $perms, $list, $computed, $help);
188
        }
189
        $err1 = $this->errno;
190
        if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') {
191
            // Add declaration of field into table
192
            $result2 = $this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled);
193
            $err2 = $this->errno;
194
            if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) {
195
                $this->error = '';
196
                $this->errno = 0;
197
                return 1;
198
            } else
199
                return -2;
200
        }
201
        else {
202
            return -1;
203
        }
204
    }
205
206
    /**
207
     * 	Add a new optional attribute.
208
     *  This is a private method. For public method, use addExtraField.
209
     *
210
     * 	@param	string	$attrname			code of attribute
211
     *  @param	int		$type				Type of attribute ('boolean', 'int', 'varchar', 'text', 'html', 'date', 'datehour','price','phone','mail','password','url','select','checkbox', ...)
212
     *  @param	string	$length				Size/length of attribute ('5', '24,8', ...)
213
     *  @param  string	$elementtype        Element type ('member', 'product', 'thirdparty', 'contact', ...)
214
     *  @param	int		$unique				Is field unique or not
215
     *  @param	int		$required			Is field required or not
216
     *  @param  string  $default_value		Default value for field (in database)
217
     *  @param  array	$param				Params for field  (ex for select list : array('options'=>array('value'=>'label of option'))
218
     *  @param	string	$perms				Permission
219
     * 	@param	string	$list				Into list view by default
220
     *  @param  string  $computed           Computed value
221
     *  @return int      	           		<=0 if KO, >0 if OK
222
     */
223
    private function create($attrname, $type = 'varchar', $length = 255, $elementtype = 'member', $unique = 0, $required = 0, $default_value = '', $param = '', $perms = '', $list = '0', $computed = '')
224
    {
225
        if ($elementtype == 'thirdparty')
226
            $elementtype = 'societe';
227
        if ($elementtype == 'contact')
228
            $elementtype = 'socpeople';
229
230
        $table = $elementtype . '_extrafields';
231
        if ($elementtype == 'categorie')
232
            $table = 'categories_extrafields';
233
234
        if (!empty($attrname) && preg_match("/^\w[a-zA-Z0-9_]*$/", $attrname) && !is_numeric($attrname)) {
235
            if ($type == 'boolean') {
236
                $typedb = 'int';
237
                $lengthdb = '1';
238
            } elseif ($type == 'price') {
239
                $typedb = 'double';
240
                $lengthdb = '24,8';
241
            } elseif ($type == 'phone') {
242
                $typedb = 'varchar';
243
                $lengthdb = '20';
244
            } elseif ($type == 'mail') {
245
                $typedb = 'varchar';
246
                $lengthdb = '128';
247
            } elseif ($type == 'url') {
248
                $typedb = 'varchar';
249
                $lengthdb = '255';
250
            } elseif (($type == 'select') || ($type == 'sellist') || ($type == 'radio') || ($type == 'checkbox') || ($type == 'chkbxlst')) {
251
                $typedb = 'varchar';
252
                $lengthdb = '255';
253
            } elseif ($type == 'link') {
254
                $typedb = 'int';
255
                $lengthdb = '11';
256
            } elseif ($type == 'html') {
257
                $typedb = 'text';
258
                $lengthdb = $length;
259
            } elseif ($type == 'password') {
260
                $typedb = 'varchar';
261
                $lengthdb = '128';
262
            } else {
263
                $typedb = $type;
264
                $lengthdb = $length;
265
                if ($type == 'varchar' && empty($lengthdb))
266
                    $lengthdb = '255';
267
            }
268
            $field_desc = array(
269
                'type' => $typedb,
270
                'value' => $lengthdb,
271
                'null' => ($required ? 'NOT NULL' : 'NULL'),
272
                'default' => $default_value
273
            );
274
275
            $result = Config::$dbEngine->DDLAddField(MAIN_DB_PREFIX . $table, $attrname, $field_desc);
0 ignored issues
show
Bug introduced by
The method DDLAddField() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

275
            /** @scrutinizer ignore-call */ $result = Config::$dbEngine->DDLAddField(MAIN_DB_PREFIX . $table, $attrname, $field_desc);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
276
            if ($result > 0) {
277
                if ($unique) {
278
                    $sql = "ALTER TABLE " . MAIN_DB_PREFIX . $table . " ADD UNIQUE INDEX uk_" . $table . "_" . $attrname . " (" . $attrname . ")";
279
                    $resql = Config::$dbEngine->query($sql, 1, 'dml');
0 ignored issues
show
Bug introduced by
The method query() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

279
                    /** @scrutinizer ignore-call */ $resql = Config::$dbEngine->query($sql, 1, 'dml');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
280
                }
281
                return 1;
282
            } else {
283
                $this->error = Config::$dbEngine->lasterror();
0 ignored issues
show
Bug introduced by
The method lasterror() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

283
                /** @scrutinizer ignore-call */ $this->error = Config::$dbEngine->lasterror();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
284
                $this->errno = Config::$dbEngine->lasterrno();
0 ignored issues
show
Bug introduced by
The method lasterrno() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

284
                /** @scrutinizer ignore-call */ $this->errno = Config::$dbEngine->lasterrno();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
285
                return -1;
286
            }
287
        } else {
288
            return 0;
289
        }
290
    }
291
292
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
293
    /**
294
     * 	Add description of a new optional attribute
295
     *
296
     * 	@param	string			$attrname		code of attribute
297
     * 	@param	string			$label			label of attribute
298
     *  @param	int				$type			Type of attribute ('int', 'varchar', 'text', 'html', 'date', 'datehour', 'float')
299
     *  @param	int				$pos			Position of attribute
300
     *  @param	string			$size			Size/length of attribute ('5', '24,8', ...)
301
     *  @param  string			$elementtype	Element type ('member', 'product', 'thirdparty', ...)
302
     *  @param	int				$unique			Is field unique or not
303
     *  @param	int				$required		Is field required or not
304
     *  @param  array|string	$param			Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
305
     *  @param  int				$alwayseditable	Is attribute always editable regardless of the document status
306
     *  @param	string			$perms			Permission to check
307
     *  @param	string			$list			Visibily
308
     *  @param	string			$help			Help on tooltip
309
     *  @param  string          $default        Default value (in database. use the default_value feature for default value on screen).
310
     *  @param  string          $computed       Computed value
311
     *  @param  string          $entity     	Entity of extrafields
312
     *  @param	string			$langfile		Language file
313
     *  @param  string  		$enabled  		Condition to have the field enabled or not
314
     *  @return	int								<=0 if KO, >0 if OK
315
     */
316
    private function create_label($attrname, $label = '', $type = '', $pos = 0, $size = 0, $elementtype = 'member', $unique = 0, $required = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1')
317
    {
318
        // phpcs:enable
319
        // global $conf, $user;
320
321
        if ($elementtype == 'thirdparty')
322
            $elementtype = 'societe';
323
        if ($elementtype == 'contact')
324
            $elementtype = 'socpeople';
325
326
        // Clean parameters
327
        if (empty($pos))
328
            $pos = 0;
329
        if (empty($list))
330
            $list = '0';
331
        if (empty($required))
332
            $required = 0;
333
        if (empty($unique))
334
            $unique = 0;
335
        if (empty($alwayseditable))
336
            $alwayseditable = 0;
337
338
        if (!empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/", $attrname) && !is_numeric($attrname)) {
339
            if (is_array($param) && count($param) > 0) {
340
                $params = serialize($param);
341
            } elseif (strlen($param) > 0) {
342
                $params = trim($param);
343
            } else {
344
                $params = '';
345
            }
346
347
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "extrafields(";
348
            $sql .= " name,";
349
            $sql .= " label,";
350
            $sql .= " type,";
351
            $sql .= " pos,";
352
            $sql .= " size,";
353
            $sql .= " entity,";
354
            $sql .= " elementtype,";
355
            $sql .= " fieldunique,";
356
            $sql .= " fieldrequired,";
357
            $sql .= " param,";
358
            $sql .= " alwayseditable,";
359
            $sql .= " perms,";
360
            $sql .= " langs,";
361
            $sql .= " list,";
362
            $sql .= " fielddefault,";
363
            $sql .= " fieldcomputed,";
364
            $sql .= " fk_user_author,";
365
            $sql .= " fk_user_modif,";
366
            $sql .= " datec,";
367
            $sql .= " enabled,";
368
            $sql .= " help";
369
            $sql .= " )";
370
            $sql .= " VALUES('" . $attrname . "',";
371
            $sql .= " '" . Config::$dbEngine->escape($label) . "',";
0 ignored issues
show
Bug introduced by
The method escape() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

371
            $sql .= " '" . Config::$dbEngine->/** @scrutinizer ignore-call */ escape($label) . "',";

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
372
            $sql .= " '" . Config::$dbEngine->escape($type) . "',";
373
            $sql .= " " . $pos . ",";
374
            $sql .= " '" . Config::$dbEngine->escape($size) . "',";
375
            $sql .= " " . ($entity === '' ? Globals::$conf->entity : $entity) . ",";
376
            $sql .= " '" . Config::$dbEngine->escape($elementtype) . "',";
377
            $sql .= " " . $unique . ",";
378
            $sql .= " " . $required . ",";
379
            $sql .= " '" . Config::$dbEngine->escape($params) . "',";
380
            $sql .= " " . $alwayseditable . ",";
381
            $sql .= " " . ($perms ? "'" . Config::$dbEngine->escape($perms) . "'" : "null") . ",";
382
            $sql .= " " . ($langfile ? "'" . Config::$dbEngine->escape($langfile) . "'" : "null") . ",";
383
            $sql .= " '" . Config::$dbEngine->escape($list) . "',";
384
            $sql .= " " . ($default ? "'" . Config::$dbEngine->escape($default) . "'" : "null") . ",";
385
            $sql .= " " . ($computed ? "'" . Config::$dbEngine->escape($computed) . "'" : "null") . ",";
386
            $sql .= " " . (is_object(Globals::$user) ? Globals::$user->id : 0) . ",";
387
            $sql .= " " . (is_object(Globals::$user) ? Globals::$user->id : 0) . ",";
388
            $sql .= "'" . Config::$dbEngine->idate(dol_now()) . "',";
0 ignored issues
show
Bug introduced by
The method idate() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

388
            $sql .= "'" . Config::$dbEngine->/** @scrutinizer ignore-call */ idate(dol_now()) . "',";

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
389
            $sql .= " " . ($enabled ? "'" . Config::$dbEngine->escape($enabled) . "'" : "1") . ",";
390
            $sql .= " " . ($help ? "'" . Config::$dbEngine->escape($help) . "'" : "null");
391
            $sql .= ')';
392
393
            AlDolUtils::dol_syslog(get_class($this) . "::create_label", LOG_DEBUG);
394
            if (Config::$dbEngine->query($sql)) {
395
                return 1;
396
            } else {
397
                $this->error = Config::$dbEngine->lasterror();
398
                $this->errno = Config::$dbEngine->lasterrno();
399
                return -1;
400
            }
401
        }
402
    }
403
404
    /**
405
     * 	Delete an optional attribute
406
     *
407
     * 	@param	string	$attrname		Code of attribute to delete
408
     *  @param  string	$elementtype    Element type ('member', 'product', 'thirdparty', 'contact', ...)
409
     *  @return int              		< 0 if KO, 0 if nothing is done, 1 if OK
410
     */
411
    function delete($attrname, $elementtype = 'member')
412
    {
413
        if ($elementtype == 'thirdparty')
414
            $elementtype = 'societe';
415
        if ($elementtype == 'contact')
416
            $elementtype = 'socpeople';
417
418
        $table = $elementtype . '_extrafields';
419
        if ($elementtype == 'categorie')
420
            $table = 'categories_extrafields';
421
422
        $error = 0;
423
424
        if (!empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/", $attrname)) {
425
            $result = $this->delete_label($attrname, $elementtype);
426
            if ($result < 0) {
427
                $this->error = Config::$dbEngine->lasterror();
428
                $error++;
429
            }
430
431
            if (!$error) {
432
                $sql = "SELECT COUNT(rowid) as nb";
433
                $sql .= " FROM " . MAIN_DB_PREFIX . "extrafields";
434
                $sql .= " WHERE elementtype = '" . $elementtype . "'";
435
                $sql .= " AND name = '" . $attrname . "'";
436
                //$sql.= " AND entity IN (0,".Globals::$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
437
                $resql = Config::$dbEngine->query($sql);
438
                if ($resql) {
439
                    $obj = Config::$dbEngine->fetch_object($resql);
0 ignored issues
show
Bug introduced by
The method fetch_object() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

439
                    /** @scrutinizer ignore-call */ $obj = Config::$dbEngine->fetch_object($resql);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
440
                    if ($obj->nb <= 0) {
441
                        $result = Config::$dbEngine->DDLDropField(MAIN_DB_PREFIX . $table, $attrname); // This also drop the unique key
0 ignored issues
show
Bug introduced by
The method DDLDropField() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

441
                        /** @scrutinizer ignore-call */ $result = Config::$dbEngine->DDLDropField(MAIN_DB_PREFIX . $table, $attrname); // This also drop the unique key

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
442
                        if ($result < 0) {
443
                            $this->error = Config::$dbEngine->lasterror();
444
                            $error++;
445
                        }
446
                    }
447
                }
448
            }
449
450
            return $result;
451
        } else {
452
            return 0;
453
        }
454
    }
455
456
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
457
    /**
458
     * 	Delete description of an optional attribute
459
     *
460
     * 	@param	string	$attrname			Code of attribute to delete
461
     *  @param  string	$elementtype        Element type ('member', 'product', 'thirdparty', ...)
462
     *  @return int              			< 0 if KO, 0 if nothing is done, 1 if OK
463
     */
464
    private function delete_label($attrname, $elementtype = 'member')
465
    {
466
        // phpcs:enable
467
        // global $conf;
468
469
        if ($elementtype == 'thirdparty')
470
            $elementtype = 'societe';
471
        if ($elementtype == 'contact')
472
            $elementtype = 'socpeople';
473
474
        if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/", $attrname)) {
475
            $sql = "DELETE FROM " . MAIN_DB_PREFIX . "extrafields";
476
            $sql .= " WHERE name = '" . $attrname . "'";
477
            $sql .= " AND entity IN  (0," . Globals::$conf->entity . ')';
478
            $sql .= " AND elementtype = '" . $elementtype . "'";
479
480
            AlDolUtils::dol_syslog(get_class($this) . "::delete_label", LOG_DEBUG);
481
            $resql = Config::$dbEngine->query($sql);
482
            if ($resql) {
483
                return 1;
484
            } else {
485
                print dol_print_error(Config::$dbEngine);
0 ignored issues
show
Bug introduced by
Are you sure the usage of dol_print_error(Alxarafe\Helpers\Config::dbEngine) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
486
                return -1;
487
            }
488
        } else {
489
            return 0;
490
        }
491
    }
492
493
    /**
494
     * 	Modify type of a personalized attribute
495
     *
496
     *  @param	string	$attrname			Name of attribute
497
     *  @param	string	$label				Label of attribute
498
     *  @param	string	$type				Type of attribute ('boolean', 'int', 'varchar', 'text', 'html', 'date', 'datehour','price','phone','mail','password','url','select','checkbox', ...)
499
     *  @param	int		$length				Length of attribute
500
     *  @param  string	$elementtype        Element type ('member', 'product', 'thirdparty', 'contact', ...)
501
     *  @param	int		$unique				Is field unique or not
502
     *  @param	int		$required			Is field required or not
503
     *  @param	int		$pos				Position of attribute
504
     *  @param  array	$param				Params for field (ex for select list : array('options' => array(value'=>'label of option')) )
505
     *  @param  int		$alwayseditable		Is attribute always editable regardless of the document status
506
     *  @param	string	$perms				Permission to check
507
     *  @param	string	$list				Visibility
508
     *  @param	string	$help				Help on tooltip
509
     *  @param  string  $default            Default value (in database. use the default_value feature for default value on screen).
510
     *  @param  string  $computed           Computed value
511
     *  @param  string  $entity	            Entity of extrafields
512
     *  @param	string	$langfile			Language file
513
     *  @param  string  $enabled  			Condition to have the field enabled or not
514
     *  @param  int     $totalizable        Is extrafield totalizable on list
515
     * 	@return	int							>0 if OK, <=0 if KO
516
     */
517
    function update($attrname, $label, $type, $length, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0)
518
    {
519
        if ($elementtype == 'thirdparty')
520
            $elementtype = 'societe';
521
        if ($elementtype == 'contact')
522
            $elementtype = 'socpeople';
523
524
        $table = $elementtype . '_extrafields';
525
        if ($elementtype == 'categorie')
526
            $table = 'categories_extrafields';
527
528
        if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/", $attrname)) {
529
            if ($type == 'boolean') {
530
                $typedb = 'int';
531
                $lengthdb = '1';
532
            } elseif ($type == 'price') {
533
                $typedb = 'double';
534
                $lengthdb = '24,8';
535
            } elseif ($type == 'phone') {
536
                $typedb = 'varchar';
537
                $lengthdb = '20';
538
            } elseif ($type == 'mail') {
539
                $typedb = 'varchar';
540
                $lengthdb = '128';
541
            } elseif ($type == 'url') {
542
                $typedb = 'varchar';
543
                $lengthdb = '255';
544
            } elseif (($type == 'select') || ($type == 'sellist') || ($type == 'radio') || ($type == 'checkbox') || ($type == 'chkbxlst')) {
545
                $typedb = 'varchar';
546
                $lengthdb = '255';
547
            } elseif ($type == 'html') {
548
                $typedb = 'text';
549
            } elseif ($type == 'link') {
550
                $typedb = 'int';
551
                $lengthdb = '11';
552
            } elseif ($type == 'password') {
553
                $typedb = 'varchar';
554
                $lengthdb = '50';
555
            } else {
556
                $typedb = $type;
557
                $lengthdb = $length;
558
            }
559
            $field_desc = array('type' => $typedb, 'value' => $lengthdb, 'null' => ($required ? 'NOT NULL' : 'NULL'), 'default' => $default);
560
561
            if ($type != 'separate') { // No table update when separate type
562
                $result = Config::$dbEngine->DDLUpdateField(MAIN_DB_PREFIX . $table, $attrname, $field_desc);
0 ignored issues
show
Bug introduced by
The method DDLUpdateField() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

562
                /** @scrutinizer ignore-call */ $result = Config::$dbEngine->DDLUpdateField(MAIN_DB_PREFIX . $table, $attrname, $field_desc);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
563
            }
564
            if ($result > 0 || $type == 'separate') {
565
                if ($label) {
566
                    $result = $this->update_label($attrname, $label, $type, $length, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default, $computed, $entity, $langfile, $enabled, $totalizable);
567
                }
568
                if ($result > 0) {
569
                    $sql = '';
570
                    if ($unique) {
571
                        $sql = "ALTER TABLE " . MAIN_DB_PREFIX . $table . " ADD UNIQUE INDEX uk_" . $table . "_" . $attrname . " (" . $attrname . ")";
572
                    } else {
573
                        $sql = "ALTER TABLE " . MAIN_DB_PREFIX . $table . " DROP INDEX uk_" . $table . "_" . $attrname;
574
                    }
575
                    AlDolUtils::dol_syslog(get_class($this) . '::update', LOG_DEBUG);
576
                    $resql = Config::$dbEngine->query($sql, 1, 'dml');
577
                    return 1;
578
                } else {
579
                    $this->error = Config::$dbEngine->lasterror();
580
                    return -1;
581
                }
582
            } else {
583
                $this->error = Config::$dbEngine->lasterror();
584
                return -1;
585
            }
586
        } else {
587
            return 0;
588
        }
589
    }
590
591
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
592
    /**
593
     *  Modify description of personalized attribute
594
     *
595
     *  @param	string	$attrname			Name of attribute
596
     *  @param	string	$label				Label of attribute
597
     *  @param  string	$type               Type of attribute
598
     *  @param  int		$size		        Length of attribute
599
     *  @param  string	$elementtype		Element type ('member', 'product', 'thirdparty', ...)
600
     *  @param	int		$unique				Is field unique or not
601
     *  @param	int		$required			Is field required or not
602
     *  @param	int		$pos				Position of attribute
603
     *  @param  array	$param				Params for field  (ex for select list : array('options' => array(value'=>'label of option')) )
604
     *  @param  int		$alwayseditable		Is attribute always editable regardless of the document status
605
     *  @param	string	$perms				Permission to check
606
     *  @param	string	$list				Visiblity
607
     *  @param	string	$help				Help on tooltip.
608
     *  @param  string  $default            Default value (in database. use the default_value feature for default value on screen).
609
     *  @param  string  $computed           Computed value
610
     *  @param  string  $entity     		Entity of extrafields
611
     *  @param	string	$langfile			Language file
612
     *  @param  string  $enabled  			Condition to have the field enabled or not
613
     *  @param  int     $totalizable        Is extrafield totalizable on list
614
     *  @return	int							<=0 if KO, >0 if OK
615
     */
616
    private function update_label($attrname, $label, $type, $size, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '0', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0)
617
    {
618
        // phpcs:enable
619
        // global $conf, $user;
620
        AlDolUtils::dol_syslog(get_class($this) . "::update_label " . $attrname . ", " . $label . ", " . $type . ", " . $size . ", " . $elementtype . ", " . $unique . ", " . $required . ", " . $pos . ", " . $alwayseditable . ", " . $perms . ", " . $list . ", " . $default . ", " . $computed . ", " . $entity . ", " . $langfile . ", " . $enabled . ", " . $totalizable);
621
622
        // Clean parameters
623
        if ($elementtype == 'thirdparty')
624
            $elementtype = 'societe';
625
        if ($elementtype == 'contact')
626
            $elementtype = 'socpeople';
627
628
        if (empty($pos))
629
            $pos = 0;
630
        if (empty($list))
631
            $list = '0';
632
        if (empty($totalizable)) {
633
            $totalizable = 0;
634
        }
635
        if (empty($required))
636
            $required = 0;
637
        if (empty($unique))
638
            $unique = 0;
639
        if (empty($alwayseditable))
640
            $alwayseditable = 0;
641
642
        if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/", $attrname)) {
643
            Config::$dbEngine->begin();
0 ignored issues
show
Bug introduced by
The method begin() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

643
            Config::$dbEngine->/** @scrutinizer ignore-call */ 
644
                               begin();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
644
645
            if (is_array($param) && count($param) > 0) {
646
                $params = serialize($param);
647
            } elseif (strlen($param) > 0) {
648
                $params = trim($param);
649
            } else {
650
                $params = '';
651
            }
652
653
            if ($entity === '' || $entity != '0') {
654
                // We dont want on all entities, we delete all and current
655
                $sql_del = "DELETE FROM " . MAIN_DB_PREFIX . "extrafields";
656
                $sql_del .= " WHERE name = '" . $attrname . "'";
657
                $sql_del .= " AND entity IN (0, " . ($entity === '' ? Globals::$conf->entity : $entity) . ")";
658
                $sql_del .= " AND elementtype = '" . $elementtype . "'";
659
            } else {
660
                // We want on all entities ($entities = '0'), we delete on all only (we keep setup specific to each entity)
661
                $sql_del = "DELETE FROM " . MAIN_DB_PREFIX . "extrafields";
662
                $sql_del .= " WHERE name = '" . $attrname . "'";
663
                $sql_del .= " AND entity = 0";
664
                $sql_del .= " AND elementtype = '" . $elementtype . "'";
665
            }
666
            $resql1 = Config::$dbEngine->query($sql_del);
667
668
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "extrafields(";
669
            $sql .= " name,";  // This is code
670
            $sql .= " entity,";
671
            $sql .= " label,";
672
            $sql .= " type,";
673
            $sql .= " size,";
674
            $sql .= " elementtype,";
675
            $sql .= " fieldunique,";
676
            $sql .= " fieldrequired,";
677
            $sql .= " perms,";
678
            $sql .= " langs,";
679
            $sql .= " pos,";
680
            $sql .= " alwayseditable,";
681
            $sql .= " param,";
682
            $sql .= " list,";
683
            $sql .= " totalizable,";
684
            $sql .= " fielddefault,";
685
            $sql .= " fieldcomputed,";
686
            $sql .= " fk_user_author,";
687
            $sql .= " fk_user_modif,";
688
            $sql .= " datec,";
689
            $sql .= " enabled,";
690
            $sql .= " help";
691
            $sql .= ") VALUES (";
692
            $sql .= "'" . $attrname . "',";
693
            $sql .= " " . ($entity === '' ? Globals::$conf->entity : $entity) . ",";
694
            $sql .= " '" . Config::$dbEngine->escape($label) . "',";
695
            $sql .= " '" . Config::$dbEngine->escape($type) . "',";
696
            $sql .= " '" . Config::$dbEngine->escape($size) . "',";
697
            $sql .= " '" . Config::$dbEngine->escape($elementtype) . "',";
698
            $sql .= " " . $unique . ",";
699
            $sql .= " " . $required . ",";
700
            $sql .= " " . ($perms ? "'" . Config::$dbEngine->escape($perms) . "'" : "null") . ",";
701
            $sql .= " " . ($langfile ? "'" . Config::$dbEngine->escape($langfile) . "'" : "null") . ",";
702
            $sql .= " " . $pos . ",";
703
            $sql .= " '" . Config::$dbEngine->escape($alwayseditable) . "',";
704
            $sql .= " '" . Config::$dbEngine->escape($params) . "',";
705
            $sql .= " '" . Config::$dbEngine->escape($list) . "', ";
706
            $sql .= " " . $totalizable . ",";
707
            $sql .= " " . (($default != '') ? "'" . Config::$dbEngine->escape($default) . "'" : "null") . ",";
708
            $sql .= " " . ($computed ? "'" . Config::$dbEngine->escape($computed) . "'" : "null") . ",";
709
            $sql .= " " . Globals::$user->id . ",";
710
            $sql .= " " . Globals::$user->id . ",";
711
            $sql .= "'" . Config::$dbEngine->idate(dol_now()) . "',";
712
            $sql .= "'" . Config::$dbEngine->escape($enabled) . "',";
713
            $sql .= " " . ($help ? "'" . Config::$dbEngine->escape($help) . "'" : "null");
714
            $sql .= ")";
715
716
            $resql2 = Config::$dbEngine->query($sql);
717
718
            if ($resql1 && $resql2) {
719
                Config::$dbEngine->commit();
720
                return 1;
721
            } else {
722
                Config::$dbEngine->rollback();
723
                print dol_print_error(Config::$dbEngine);
0 ignored issues
show
Bug introduced by
Are you sure the usage of dol_print_error(Alxarafe\Helpers\Config::dbEngine) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
724
                return -1;
725
            }
726
        } else {
727
            return 0;
728
        }
729
    }
730
731
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
732
    /**
733
     * 	Load array this->attributes, or old this->attribute_xxx like attribute_label, attribute_type, ...
734
     *
735
     * 	@param	string		$elementtype		Type of element ('adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...).
736
     * 	@param	boolean		$forceload			Force load of extra fields whatever is option MAIN_EXTRAFIELDS_DISABLED. Deprecated. Should not be required.
737
     * 	@return	array							Array of attributes keys+label for all extra fields.
738
     */
739
    function fetch_name_optionals_label($elementtype, $forceload = false)
740
    {
741
        // phpcs:enable
742
        // global $conf;
743
744
        if (empty($elementtype))
745
            return array();
746
747
        if ($elementtype == 'thirdparty')
748
            $elementtype = 'societe';
749
        if ($elementtype == 'contact')
750
            $elementtype = 'socpeople';
751
        if ($elementtype == 'order_supplier')
752
            $elementtype = 'commande_fournisseur';
753
754
        $array_name_label = array();
755
756
        // To avoid conflicts with external modules. TODO Remove this.
757
        if (!$forceload &&!empty(Globals::$conf->global->MAIN_EXTRAFIELDS_DISABLED))
758
        return $array_name_label;
759
760
        // Set array of label of entity
761
        // TODO Remove completely loading of label. This should be done by presentation.
762
        $labelmulticompany = array();
763
        if (!empty(Globals::$conf->multicompany->enabled)) {
764
            $sql_entity_name = 'SELECT rowid, label FROM ' . MAIN_DB_PREFIX . 'entity WHERE rowid in (0,' . Globals::$conf->entity . ')';
765
            $resql_entity_name = Config::$dbEngine->query($sql_entity_name);
766
            if ($resql_entity_name) {
767
                while ($obj = Config::$dbEngine->fetch_object($resql_entity_name)) {
768
                    $labelmulticompany[$obj->rowid] = $obj->label;
769
                }
770
            }
771
        }
772
773
        // 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.
774
        AlDolUtils::dol_syslog("fetch_name_optionals_label elementtype=" . $elementtype);
775
776
        $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,totalizable,fielddefault,fieldcomputed,entity,enabled,help";
777
        $sql .= " FROM " . MAIN_DB_PREFIX . "extrafields";
778
        $sql .= " WHERE entity IN (0," . Globals::$conf->entity . ")";
779
        if ($elementtype)
780
            $sql .= " AND elementtype = '" . $elementtype . "'"; // Filed with object->table_element
781
        $sql .= " ORDER BY pos";
782
783
        $resql = Config::$dbEngine->select($sql);
784
        if ($resql) {
785
            foreach ($resql as $arrayTab) {
786
787
                // Convert array to object
788
                $tab = json_decode(json_encode($arrayTab));
789
790
                // We can add this attribute to object. TODO Remove this and return $this->attributes[$elementtype]['label']
791
                if ($tab->type != 'separate') {
792
                    $array_name_label[$tab->name] = $tab->label;
793
                }
794
795
                // Old usage
796
                $this->attribute_type[$tab->name] = $tab->type;
797
                $this->attribute_label[$tab->name] = $tab->label;
798
                $this->attribute_size[$tab->name] = $tab->size;
799
                $this->attribute_elementtype[$tab->name] = $tab->elementtype;
800
                $this->attribute_default[$tab->name] = $tab->fielddefault;
801
                $this->attribute_computed[$tab->name] = $tab->fieldcomputed;
802
                $this->attribute_unique[$tab->name] = $tab->fieldunique;
803
                $this->attribute_required[$tab->name] = $tab->fieldrequired;
804
                $this->attribute_param[$tab->name] = ($tab->param ? unserialize($tab->param) : '');
805
                $this->attribute_pos[$tab->name] = $tab->pos;
806
                $this->attribute_alwayseditable[$tab->name] = $tab->alwayseditable;
807
                $this->attribute_perms[$tab->name] = (strlen($tab->perms) == 0 ? 1 : $tab->perms);
808
                $this->attribute_langfile[$tab->name] = $tab->langs;
809
                $this->attribute_list[$tab->name] = $tab->list;
810
                $this->attribute_totalizable[$tab->name] = $tab->totalizable;
811
                $this->attribute_entityid[$tab->name] = $tab->entity;
812
                $this->attribute_entitylabel[$tab->name] = (empty($labelmulticompany[$tab->entity]) ? 'Entity' . $tab->entity : $labelmulticompany[$tab->entity]);
813
814
                // New usage
815
                $this->attributes[$tab->elementtype]['type'][$tab->name] = $tab->type;
816
                $this->attributes[$tab->elementtype]['label'][$tab->name] = $tab->label;
817
                $this->attributes[$tab->elementtype]['size'][$tab->name] = $tab->size;
818
                $this->attributes[$tab->elementtype]['elementtype'][$tab->name] = $tab->elementtype;
819
                $this->attributes[$tab->elementtype]['default'][$tab->name] = $tab->fielddefault;
820
                $this->attributes[$tab->elementtype]['computed'][$tab->name] = $tab->fieldcomputed;
821
                $this->attributes[$tab->elementtype]['unique'][$tab->name] = $tab->fieldunique;
822
                $this->attributes[$tab->elementtype]['required'][$tab->name] = $tab->fieldrequired;
823
                $this->attributes[$tab->elementtype]['param'][$tab->name] = ($tab->param ? unserialize($tab->param) : '');
824
                $this->attributes[$tab->elementtype]['pos'][$tab->name] = $tab->pos;
825
                $this->attributes[$tab->elementtype]['alwayseditable'][$tab->name] = $tab->alwayseditable;
826
                $this->attributes[$tab->elementtype]['perms'][$tab->name] = (strlen($tab->perms) == 0 ? 1 : $tab->perms);
827
                $this->attributes[$tab->elementtype]['langfile'][$tab->name] = $tab->langs;
828
                $this->attributes[$tab->elementtype]['list'][$tab->name] = $tab->list;
829
                $this->attributes[$tab->elementtype]['totalizable'][$tab->name] = $tab->totalizable;
830
                $this->attributes[$tab->elementtype]['entityid'][$tab->name] = $tab->entity;
831
                $this->attributes[$tab->elementtype]['entitylabel'][$tab->name] = (empty($labelmulticompany[$tab->entity]) ? 'Entity' . $tab->entity : $labelmulticompany[$tab->entity]);
832
                $this->attributes[$tab->elementtype]['enabled'][$tab->name] = $tab->enabled;
833
                $this->attributes[$tab->elementtype]['help'][$tab->name] = $tab->help;
834
            }
835
836
            $this->attributes[$tab->elementtype]['loaded'] = 1;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $tab seems to be defined by a foreach iteration on line 785. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
837
            if ($elementtype) {
838
                $this->attributes[$elementtype]['loaded'] = 1; // If nothing found, we also save tag 'loaded'
839
            }
840
        }
841
842
        return $array_name_label;
843
    }
844
845
    /**
846
     * Return HTML string to put an input field into a page
847
     * Code very similar with showInputField of common object
848
     *
849
     * @param  string  $key            			Key of attribute
850
     * @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)
851
     * @param  string  $moreparam      			To add more parametes on html input tag
852
     * @param  string  $keysuffix      			Prefix string to add after name and id of field (can be used to avoid duplicate names)
853
     * @param  string  $keyprefix      			Suffix string to add before name and id of field (can be used to avoid duplicate names)
854
     * @param  string  $morecss        			More css (to defined size of field. Old behaviour: may also be a numeric)
855
     * @param  int     $objectid       			Current object id
856
     * @param  string  $extrafieldsobjectkey	If defined (for example $object->table_element), use the new method to get extrafields data
857
     * @return string
858
     */
859
    function showInputField($key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '', $objectid = 0, $extrafieldsobjectkey = '')
860
    {
861
        // global $conf, $langs, $form;
862
863
        if (!is_object($form)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $form seems to be never defined.
Loading history...
864
            require_once DOL_DOCUMENT_ROOT . '/core/class/html.form.class.php';
865
            $form = new Form(Config::$dbEngine);
0 ignored issues
show
Bug introduced by
The type Alixar\Base\Form was not found. Did you mean Form? If so, make sure to prefix the type with \.
Loading history...
866
        }
867
868
        $out = '';
869
870
        $keyprefix = $keyprefix . 'options_';  // Because we work on extrafields
871
872
        if (!empty($extrafieldsobjectkey)) {
873
            $label = $this->attributes[$extrafieldsobjectkey]['label'][$key];
874
            $type = $this->attributes[$extrafieldsobjectkey]['type'][$key];
875
            $size = $this->attributes[$extrafieldsobjectkey]['size'][$key];
876
            $default = $this->attributes[$extrafieldsobjectkey]['default'][$key];
877
            $computed = $this->attributes[$extrafieldsobjectkey]['computed'][$key];
878
            $unique = $this->attributes[$extrafieldsobjectkey]['unique'][$key];
879
            $required = $this->attributes[$extrafieldsobjectkey]['required'][$key];
880
            $param = $this->attributes[$extrafieldsobjectkey]['param'][$key];
881
            $perms = dol_eval($this->attributes[$extrafieldsobjectkey]['perms'][$key], 1);
882
            $langfile = $this->attributes[$extrafieldsobjectkey]['langfile'][$key];
883
            $list = dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1);
884
            $totalizable = $this->attributes[$extrafieldsobjectkey]['totalizable'][$key];
885
            $help = $this->attributes[$extrafieldsobjectkey]['help'][$key];
886
            $hidden = (empty($list) ? 1 : 0);  // If empty, 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)
887
        } else { // Old usage
888
            $label = $this->attribute_label[$key];
889
            $type = $this->attribute_type[$key];
890
            $size = $this->attribute_size[$key];
891
            $elementtype = $this->attribute_elementtype[$key]; // Seems not used
892
            $default = $this->attribute_default[$key];
893
            $computed = $this->attribute_computed[$key];
894
            $unique = $this->attribute_unique[$key];
895
            $required = $this->attribute_required[$key];
896
            $param = $this->attribute_param[$key];
897
            $langfile = $this->attribute_langfile[$key];
898
            $list = $this->attribute_list[$key];
899
            $totalizable = $this->attribute_totalizable[$key];
900
            $hidden = (empty($list) ? 1 : 0);  // If empty, 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)
901
        }
902
903
        if ($computed) {
904
            if (!preg_match('/^search_/', $keyprefix))
905
                return '<span class="opacitymedium">' . Globals::$langs->trans("AutomaticallyCalculated") . '</span>';
906
            else
907
                return '';
908
        }
909
910
        if (empty($morecss)) {
911
            if ($type == 'date') {
912
                $morecss = 'minwidth100imp';
913
            } elseif ($type == 'datetime') {
914
                $morecss = 'minwidth200imp';
915
            } elseif (in_array($type, array('int', 'integer', 'double', 'price'))) {
916
                $morecss = 'maxwidth75';
917
            } elseif ($type == 'password') {
918
                $morecss = 'maxwidth100';
919
            } elseif ($type == 'url') {
920
                $morecss = 'minwidth400';
921
            } elseif ($type == 'boolean') {
922
                $morecss = '';
923
            } else {
924
                if (round($size) < 12) {
925
                    $morecss = 'minwidth100';
926
                } else if (round($size) <= 48) {
927
                    $morecss = 'minwidth200';
928
                } else {
929
                    $morecss = 'minwidth400';
930
                }
931
            }
932
        }
933
934
        if (in_array($type, array('date', 'datetime'))) {
935
            $tmp = explode(',', $size);
936
            $newsize = $tmp[0];
937
938
            $showtime = in_array($type, array('datetime')) ? 1 : 0;
939
940
            // Do not show current date when field not required (see selectDate() method)
941
            if (!$required && $value == '')
942
                $value = '-1';
943
944
            // TODO Must also support $moreparam
945
            $out = $form->selectDate($value, $keyprefix . $key . $keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1);
946
        }
947
        elseif (in_array($type, array('int', 'integer'))) {
948
            $tmp = explode(',', $size);
949
            $newsize = $tmp[0];
950
            $out = '<input type="text" class="flat ' . $morecss . ' maxwidthonsmartphone" name="' . $keyprefix . $key . $keysuffix . '" id="' . $keyprefix . $key . $keysuffix . '" maxlength="' . $newsize . '" value="' . dol_escape_htmltag($value) . '"' . ($moreparam ? $moreparam : '') . '>';
951
        } elseif (preg_match('/varchar/', $type)) {
952
            $out = '<input type="text" class="flat ' . $morecss . ' maxwidthonsmartphone" name="' . $keyprefix . $key . $keysuffix . '" id="' . $keyprefix . $key . $keysuffix . '" maxlength="' . $size . '" value="' . dol_escape_htmltag($value) . '"' . ($moreparam ? $moreparam : '') . '>';
953
        } elseif (in_array($type, array('mail', 'phone', 'url'))) {
954
            $out = '<input type="text" class="flat ' . $morecss . ' maxwidthonsmartphone" name="' . $keyprefix . $key . $keysuffix . '" id="' . $keyprefix . $key . $keysuffix . '" value="' . dol_escape_htmltag($value) . '" ' . ($moreparam ? $moreparam : '') . '>';
955
        } elseif ($type == 'text') {
956
            if (!preg_match('/search_/', $keyprefix)) {  // If keyprefix is search_ or search_options_, we must just use a simple text field
957
                require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
958
                $doleditor = new DolEditor($keyprefix . $key . $keysuffix, $value, '', 200, 'dolibarr_notes', 'In', false, false, false, ROWS_5, '90%');
0 ignored issues
show
Bug introduced by
The type Alixar\Base\DolEditor was not found. Did you mean DolEditor? If so, make sure to prefix the type with \.
Loading history...
959
                $out = $doleditor->Create(1);
960
            } else {
961
                $out = '<input type="text" class="flat ' . $morecss . ' maxwidthonsmartphone" name="' . $keyprefix . $key . $keysuffix . '" id="' . $keyprefix . $key . $keysuffix . '" value="' . dol_escape_htmltag($value) . '" ' . ($moreparam ? $moreparam : '') . '>';
962
            }
963
        } elseif ($type == 'html') {
964
            if (!preg_match('/search_/', $keyprefix)) {  // If keyprefix is search_ or search_options_, we must just use a simple text field
965
                require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
966
                $doleditor = new DolEditor($keyprefix . $key . $keysuffix, $value, '', 200, 'dolibarr_notes', 'In', false, false, !empty(Globals::$conf->fckeditor->enabled) && Globals::$conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_5, '90%');
967
                $out = $doleditor->Create(1);
968
            } else {
969
                $out = '<input type="text" class="flat ' . $morecss . ' maxwidthonsmartphone" name="' . $keyprefix . $key . $keysuffix . '" id="' . $keyprefix . $key . $keysuffix . '" value="' . dol_escape_htmltag($value) . '" ' . ($moreparam ? $moreparam : '') . '>';
970
            }
971
        } elseif ($type == 'boolean') {
972
            $checked = '';
973
            if (!empty($value)) {
974
                $checked = ' checked value="1" ';
975
            } else {
976
                $checked = ' value="1" ';
977
            }
978
            $out = '<input type="checkbox" class="flat ' . $morecss . ' maxwidthonsmartphone" name="' . $keyprefix . $key . $keysuffix . '" id="' . $keyprefix . $key . $keysuffix . '" ' . $checked . ' ' . ($moreparam ? $moreparam : '') . '>';
979
        } elseif ($type == 'price') {
980
            if (!empty($value)) {  // $value in memory is a php numeric, we format it into user number format.
981
                $value = price($value);
982
            }
983
            $out = '<input type="text" class="flat ' . $morecss . ' maxwidthonsmartphone" name="' . $keyprefix . $key . $keysuffix . '" id="' . $keyprefix . $key . $keysuffix . '" value="' . $value . '" ' . ($moreparam ? $moreparam : '') . '> ' . Globals::$langs->getCurrencySymbol(Globals::$conf->currency);
984
        } elseif ($type == 'double') {
985
            if (!empty($value)) {  // $value in memory is a php numeric, we format it into user number format.
986
                $value = price($value);
987
            }
988
            $out = '<input type="text" class="flat ' . $morecss . ' maxwidthonsmartphone" name="' . $keyprefix . $key . $keysuffix . '" id="' . $keyprefix . $key . $keysuffix . '" value="' . $value . '" ' . ($moreparam ? $moreparam : '') . '> ';
989
        } elseif ($type == 'select') {
990
            $out = '';
991
            if (!empty(Globals::$conf->use_javascript_ajax) &&!empty(Globals::$conf->global->MAIN_EXTRAFIELDS_USE_SELECT2)) {
992
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
993
                $out .= ajax_combobox($keyprefix . $key . $keysuffix, array(), 0);
994
            }
995
996
            $out .= '<select class="flat ' . $morecss . ' maxwidthonsmartphone" name="' . $keyprefix . $key . $keysuffix . '" id="' . $keyprefix . $key . $keysuffix . '" ' . ($moreparam ? $moreparam : '') . '>';
997
            $out .= '<option value="0">&nbsp;</option>';
998
            foreach ($param['options'] as $key => $val) {
0 ignored issues
show
introduced by
$key is overwriting one of the parameters of this function.
Loading history...
999
                if ((string) $key == '')
1000
                    continue;
1001
                list($val, $parent) = explode('|', $val);
1002
                $out .= '<option value="' . $key . '"';
1003
                $out .= (((string) $value == (string) $key) ? ' selected' : '');
1004
                $out .= (!empty($parent) ? ' parent="' . $parent . '"' : '');
1005
                $out .= '>';
1006
                if ($langfile && $val)
1007
                    $out .= Globals::$langs->trans($val);
1008
                else
1009
                    $out .= $val;
1010
                $out .= '</option>';
1011
            }
1012
            $out .= '</select>';
1013
        }
1014
        elseif ($type == 'sellist') {
1015
            $out = '';
1016
            if (!empty(Globals::$conf->use_javascript_ajax) &&!empty(Globals::$conf->global->MAIN_EXTRAFIELDS_USE_SELECT2)) {
1017
                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1018
                $out .= ajax_combobox($keyprefix . $key . $keysuffix, array(), 0);
1019
            }
1020
1021
            $out .= '<select class="flat ' . $morecss . ' maxwidthonsmartphone" name="' . $keyprefix . $key . $keysuffix . '" id="' . $keyprefix . $key . $keysuffix . '" ' . ($moreparam ? $moreparam : '') . '>';
1022
            if (is_array($param['options'])) {
1023
                $param_list = array_keys($param['options']);
1024
                $InfoFieldList = explode(":", $param_list[0]);
1025
                $parentName = '';
1026
                $parentField = '';
1027
                // 0 : tableName
1028
                // 1 : label field name
1029
                // 2 : key fields name (if differ of rowid)
1030
                // 3 : key field parent (for dependent lists)
1031
                // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
1032
                $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2] . ' as rowid');
1033
1034
1035
                if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) {
1036
                    if (strpos($InfoFieldList[4], 'extra.') !== false) {
1037
                        $keyList = 'main.' . $InfoFieldList[2] . ' as rowid';
1038
                    } else {
1039
                        $keyList = $InfoFieldList[2] . ' as rowid';
1040
                    }
1041
                }
1042
                if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) {
1043
                    list($parentName, $parentField) = explode('|', $InfoFieldList[3]);
1044
                    $keyList .= ', ' . $parentField;
1045
                }
1046
1047
                $fields_label = explode('|', $InfoFieldList[1]);
1048
                if (is_array($fields_label)) {
1049
                    $keyList .= ', ';
1050
                    $keyList .= implode(', ', $fields_label);
1051
                }
1052
1053
                $sqlwhere = '';
1054
                $sql = 'SELECT ' . $keyList;
1055
                $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0];
1056
                if (!empty($InfoFieldList[4])) {
1057
                    // can use curent entity filter
1058
                    if (strpos($InfoFieldList[4], '$ENTITY$') !== false) {
1059
                        $InfoFieldList[4] = str_replace('$ENTITY$', Globals::$conf->entity, $InfoFieldList[4]);
1060
                    }
1061
                    // can use SELECT request
1062
                    if (strpos($InfoFieldList[4], '$SEL$') !== false) {
1063
                        $InfoFieldList[4] = str_replace('$SEL$', 'SELECT', $InfoFieldList[4]);
1064
                    }
1065
1066
                    // current object id can be use into filter
1067
                    if (strpos($InfoFieldList[4], '$ID$') !== false && !empty($objectid)) {
1068
                        $InfoFieldList[4] = str_replace('$ID$', $objectid, $InfoFieldList[4]);
1069
                    } else {
1070
                        $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]);
1071
                    }
1072
                    //We have to join on extrafield table
1073
                    if (strpos($InfoFieldList[4], 'extra') !== false) {
1074
                        $sql .= ' as main, ' . MAIN_DB_PREFIX . $InfoFieldList[0] . '_extrafields as extra';
1075
                        $sqlwhere .= ' WHERE extra.fk_object=main.' . $InfoFieldList[2] . ' AND ' . $InfoFieldList[4];
1076
                    } else {
1077
                        $sqlwhere .= ' WHERE ' . $InfoFieldList[4];
1078
                    }
1079
                } else {
1080
                    $sqlwhere .= ' WHERE 1=1';
1081
                }
1082
                // Some tables may have field, some other not. For the moment we disable it.
1083
                if (in_array($InfoFieldList[0], array('tablewithentity'))) {
1084
                    $sqlwhere .= ' AND entity = ' . Globals::$conf->entity;
1085
                }
1086
                $sql .= $sqlwhere;
1087
                //print $sql;
1088
1089
                $sql .= ' ORDER BY ' . implode(', ', $fields_label);
1090
1091
                AlDolUtils::dol_syslog(get_class($this) . '::showInputField type=sellist', LOG_DEBUG);
1092
                $resql = Config::$dbEngine->query($sql);
1093
                if ($resql) {
1094
                    $out .= '<option value="0">&nbsp;</option>';
1095
                    $num = Config::$dbEngine->num_rows($resql);
0 ignored issues
show
Bug introduced by
The method num_rows() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1095
                    /** @scrutinizer ignore-call */ $num = Config::$dbEngine->num_rows($resql);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1096
                    $i = 0;
1097
                    while ($i < $num) {
1098
                        $labeltoshow = '';
1099
                        $obj = Config::$dbEngine->fetch_object($resql);
1100
1101
                        // Several field into label (eq table:code|libelle:rowid)
1102
                        $notrans = false;
1103
                        $fields_label = explode('|', $InfoFieldList[1]);
1104
                        if (is_array($fields_label)) {
1105
                            $notrans = true;
1106
                            foreach ($fields_label as $field_toshow) {
1107
                                $labeltoshow .= $obj->$field_toshow . ' ';
1108
                            }
1109
                        } else {
1110
                            $labeltoshow = $obj->{$InfoFieldList[1]};
1111
                        }
1112
                        $labeltoshow = dol_trunc($labeltoshow, 45);
1113
1114
                        if ($value == $obj->rowid) {
1115
                            foreach ($fields_label as $field_toshow) {
1116
                                $translabel = Globals::$langs->trans($obj->$field_toshow);
1117
                                if ($translabel != $obj->$field_toshow) {
1118
                                    $labeltoshow = dol_trunc($translabel, 18) . ' ';
1119
                                } else {
1120
                                    $labeltoshow = dol_trunc($obj->$field_toshow, 18) . ' ';
1121
                                }
1122
                            }
1123
                            $out .= '<option value="' . $obj->rowid . '" selected>' . $labeltoshow . '</option>';
1124
                        } else {
1125
                            if (!$notrans) {
1126
                                $translabel = Globals::$langs->trans($obj->{$InfoFieldList[1]});
1127
                                if ($translabel != $obj->{$InfoFieldList[1]}) {
1128
                                    $labeltoshow = dol_trunc($translabel, 18);
1129
                                } else {
1130
                                    $labeltoshow = dol_trunc($obj->{$InfoFieldList[1]}, 18);
1131
                                }
1132
                            }
1133
                            if (empty($labeltoshow))
1134
                                $labeltoshow = '(not defined)';
1135
                            if ($value == $obj->rowid) {
1136
                                $out .= '<option value="' . $obj->rowid . '" selected>' . $labeltoshow . '</option>';
1137
                            }
1138
1139
                            if (!empty($InfoFieldList[3]) && $parentField) {
1140
                                $parent = $parentName . ':' . $obj->{$parentField};
1141
                            }
1142
1143
                            $out .= '<option value="' . $obj->rowid . '"';
1144
                            $out .= ($value == $obj->rowid ? ' selected' : '');
1145
                            $out .= (!empty($parent) ? ' parent="' . $parent . '"' : '');
1146
                            $out .= '>' . $labeltoshow . '</option>';
1147
                        }
1148
1149
                        $i++;
1150
                    }
1151
                    Config::$dbEngine->free($resql);
0 ignored issues
show
Bug introduced by
The method free() does not exist on Alxarafe\Database\Engine. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1151
                    Config::$dbEngine->/** @scrutinizer ignore-call */ 
1152
                                       free($resql);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1152
                } else {
1153
                    print 'Error in request ' . $sql . ' ' . Config::$dbEngine->lasterror() . '. Check setup of extra parameters.<br>';
1154
                }
1155
            }
1156
            $out .= '</select>';
1157
        } elseif ($type == 'checkbox') {
1158
            $value_arr = explode(',', $value);
1159
            $out = $form->multiselectarray($keyprefix . $key . $keysuffix, (empty($param['options']) ? null : $param['options']), $value_arr, '', 0, '', 0, '100%');
1160
        } elseif ($type == 'radio') {
1161
            $out = '';
1162
            foreach ($param['options'] as $keyopt => $val) {
1163
                $out .= '<input class="flat ' . $morecss . '" type="radio" name="' . $keyprefix . $key . $keysuffix . '" id="' . $keyprefix . $key . $keysuffix . '" ' . ($moreparam ? $moreparam : '');
1164
                $out .= ' value="' . $keyopt . '"';
1165
                $out .= ' id="' . $keyprefix . $key . $keysuffix . '_' . $keyopt . '"';
1166
                $out .= ($value == $keyopt ? 'checked' : '');
1167
                $out .= '/><label for="' . $keyprefix . $key . $keysuffix . '_' . $keyopt . '">' . $val . '</label><br>';
1168
            }
1169
        } elseif ($type == 'chkbxlst') {
1170
            if (is_array($value)) {
1171
                $value_arr = $value;
1172
            } else {
1173
                $value_arr = explode(',', $value);
1174
            }
1175
1176
            if (is_array($param['options'])) {
1177
                $param_list = array_keys($param['options']);
1178
                $InfoFieldList = explode(":", $param_list[0]);
1179
                $parentName = '';
1180
                $parentField = '';
1181
                // 0 : tableName
1182
                // 1 : label field name
1183
                // 2 : key fields name (if differ of rowid)
1184
                // 3 : key field parent (for dependent lists)
1185
                // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
1186
                $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2] . ' as rowid');
1187
1188
                if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) {
1189
                    list ( $parentName, $parentField ) = explode('|', $InfoFieldList[3]);
1190
                    $keyList .= ', ' . $parentField;
1191
                }
1192
                if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) {
1193
                    if (strpos($InfoFieldList[4], 'extra.') !== false) {
1194
                        $keyList = 'main.' . $InfoFieldList[2] . ' as rowid';
1195
                    } else {
1196
                        $keyList = $InfoFieldList[2] . ' as rowid';
1197
                    }
1198
                }
1199
1200
                $fields_label = explode('|', $InfoFieldList[1]);
1201
                if (is_array($fields_label)) {
1202
                    $keyList .= ', ';
1203
                    $keyList .= implode(', ', $fields_label);
1204
                }
1205
1206
                $sqlwhere = '';
1207
                $sql = 'SELECT ' . $keyList;
1208
                $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0];
1209
                if (!empty($InfoFieldList[4])) {
1210
1211
                    // can use SELECT request
1212
                    if (strpos($InfoFieldList[4], '$SEL$') !== false) {
1213
                        $InfoFieldList[4] = str_replace('$SEL$', 'SELECT', $InfoFieldList[4]);
1214
                    }
1215
1216
                    // current object id can be use into filter
1217
                    if (strpos($InfoFieldList[4], '$ID$') !== false && !empty($objectid)) {
1218
                        $InfoFieldList[4] = str_replace('$ID$', $objectid, $InfoFieldList[4]);
1219
                    } else if (preg_match("#^.*list.php$#", $_SERVER["DOCUMENT_URI"])) {
1220
                        // Pattern for word=$ID$
1221
                        $word = '\b[a-zA-Z0-9-\.-_]+\b=\$ID\$';
1222
1223
                        // Removing space arount =, ( and )
1224
                        $InfoFieldList[4] = preg_replace('# *(=|\(|\)) *#', '$1', $InfoFieldList[4]);
1225
1226
                        $nbPreg = 1;
1227
                        // While we have parenthesis
1228
                        while ($nbPreg != 0) {
1229
                            // Init des compteurs
1230
                            $nbPregRepl = $nbPregSel = 0;
1231
                            // On retire toutes les parenthèses sans = avant
1232
                            $InfoFieldList[4] = preg_replace('#([^=])(\([^)^(]*(' . $word . ')[^)^(]*\))#', '$1 $3 ', $InfoFieldList[4], -1, $nbPregRepl);
1233
                            // On retire les espaces autour des = et parenthèses
1234
                            $InfoFieldList[4] = preg_replace('# *(=|\(|\)) *#', '$1', $InfoFieldList[4]);
1235
                            // On retire toutes les parenthèses avec = avant
1236
                            $InfoFieldList[4] = preg_replace('#\b[a-zA-Z0-9-\.-_]+\b=\([^)^(]*(' . $word . ')[^)^(]*\)#', '$1 ', $InfoFieldList[4], -1, $nbPregSel);
1237
                            // On retire les espaces autour des = et parenthèses
1238
                            $InfoFieldList[4] = preg_replace('# *(=|\(|\)) *#', '$1', $InfoFieldList[4]);
1239
1240
                            // Calcul du compteur général pour la boucle
1241
                            $nbPreg = $nbPregRepl + $nbPregSel;
1242
                        }
1243
1244
                        // Si l'on a un AND ou un OR, avant ou après
1245
                        preg_match('#(AND|OR|) *(' . $word . ') *(AND|OR|)#', $InfoFieldList[4], $matchCondition);
1246
                        while (!empty($matchCondition[0])) {
1247
                            // If the two sides differ but are not empty
1248
                            if (!empty($matchCondition[1]) && !empty($matchCondition[3]) && $matchCondition[1] != $matchCondition[3]) {
1249
                                // Nobody sain would do that without parentheses
1250
                                $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]);
1251
                            } else {
1252
                                if (!empty($matchCondition[1])) {
1253
                                    $boolCond = (( $matchCondition[1] == "AND" ) ? ' AND 1 ' : ' OR 0 ');
1254
                                    $InfoFieldList[4] = str_replace($matchCondition[0], $boolCond . $matchCondition[3], $InfoFieldList[4]);
1255
                                } else if (!empty($matchCondition[3])) {
1256
                                    $boolCond = (( $matchCondition[3] == "AND" ) ? ' 1 AND ' : ' 0 OR');
1257
                                    $InfoFieldList[4] = str_replace($matchCondition[0], $boolCond, $InfoFieldList[4]);
1258
                                } else {
1259
                                    $InfoFieldList[4] = 1;
1260
                                }
1261
                            }
1262
1263
                            // Si l'on a un AND ou un OR, avant ou après
1264
                            preg_match('#(AND|OR|) *(' . $word . ') *(AND|OR|)#', $InfoFieldList[4], $matchCondition);
1265
                        }
1266
                    } else {
1267
                        $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]);
1268
                    }
1269
1270
                    // We have to join on extrafield table
1271
                    if (strpos($InfoFieldList[4], 'extra') !== false) {
1272
                        $sql .= ' as main, ' . MAIN_DB_PREFIX . $InfoFieldList[0] . '_extrafields as extra';
1273
                        $sqlwhere .= ' WHERE extra.fk_object=main.' . $InfoFieldList[2] . ' AND ' . $InfoFieldList[4];
1274
                    } else {
1275
                        $sqlwhere .= ' WHERE ' . $InfoFieldList[4];
1276
                    }
1277
                } else {
1278
                    $sqlwhere .= ' WHERE 1=1';
1279
                }
1280
                // Some tables may have field, some other not. For the moment we disable it.
1281
                if (in_array($InfoFieldList[0], array('tablewithentity'))) {
1282
                    $sqlwhere .= ' AND entity = ' . Globals::$conf->entity;
1283
                }
1284
                // $sql.=preg_replace('/^ AND /','',$sqlwhere);
1285
                // print $sql;
1286
1287
                $sql .= $sqlwhere;
1288
                AlDolUtils::dol_syslog(get_class($this) . '::showInputField type=chkbxlst', LOG_DEBUG);
1289
                $resql = Config::$dbEngine->query($sql);
1290
                if ($resql) {
1291
                    $num = Config::$dbEngine->num_rows($resql);
1292
                    $i = 0;
1293
1294
                    $data = array();
1295
1296
                    while ($i < $num) {
1297
                        $labeltoshow = '';
1298
                        $obj = Config::$dbEngine->fetch_object($resql);
1299
1300
                        $notrans = false;
1301
                        // Several field into label (eq table:code|libelle:rowid)
1302
                        $fields_label = explode('|', $InfoFieldList[1]);
1303
                        if (is_array($fields_label)) {
1304
                            $notrans = true;
1305
                            foreach ($fields_label as $field_toshow) {
1306
                                $labeltoshow .= $obj->$field_toshow . ' ';
1307
                            }
1308
                        } else {
1309
                            $labeltoshow = $obj->{$InfoFieldList[1]};
1310
                        }
1311
                        $labeltoshow = dol_trunc($labeltoshow, 45);
1312
1313
                        if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1314
                            foreach ($fields_label as $field_toshow) {
1315
                                $translabel = Globals::$langs->trans($obj->$field_toshow);
1316
                                if ($translabel != $obj->$field_toshow) {
1317
                                    $labeltoshow = dol_trunc($translabel, 18) . ' ';
1318
                                } else {
1319
                                    $labeltoshow = dol_trunc($obj->$field_toshow, 18) . ' ';
1320
                                }
1321
                            }
1322
1323
                            $data[$obj->rowid] = $labeltoshow;
1324
                        } else {
1325
                            if (!$notrans) {
1326
                                $translabel = Globals::$langs->trans($obj->{$InfoFieldList[1]});
1327
                                if ($translabel != $obj->{$InfoFieldList[1]}) {
1328
                                    $labeltoshow = dol_trunc($translabel, 18);
1329
                                } else {
1330
                                    $labeltoshow = dol_trunc($obj->{$InfoFieldList[1]}, 18);
1331
                                }
1332
                            }
1333
                            if (empty($labeltoshow))
1334
                                $labeltoshow = '(not defined)';
1335
1336
                            if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1337
                                $data[$obj->rowid] = $labeltoshow;
1338
                            }
1339
1340
                            if (!empty($InfoFieldList[3]) && $parentField) {
1341
                                $parent = $parentName . ':' . $obj->{$parentField};
1342
                            }
1343
1344
                            $data[$obj->rowid] = $labeltoshow;
1345
                        }
1346
1347
                        $i ++;
1348
                    }
1349
                    Config::$dbEngine->free($resql);
1350
1351
                    $out = $form->multiselectarray($keyprefix . $key . $keysuffix, $data, $value_arr, '', 0, '', 0, '100%');
1352
                } else {
1353
                    print 'Error in request ' . $sql . ' ' . Config::$dbEngine->lasterror() . '. Check setup of extra parameters.<br>';
1354
                }
1355
            }
1356
        } elseif ($type == 'link') {
1357
            $param_list = array_keys($param['options']);    // $param_list='ObjectName:classPath'
1358
            $showempty = (($required && $default != '') ? 0 : 1);
1359
            $out = $form->selectForForms($param_list[0], $keyprefix . $key . $keysuffix, $value, $showempty);
1360
        } elseif ($type == 'password') {
1361
            // If prefix is 'search_', field is used as a filter, we use a common text field.
1362
            $out = '<input style="display:none" type="text" name="fakeusernameremembered">'; // Hidden field to reduce impact of evil Google Chrome autopopulate bug.
1363
            $out .= '<input autocomplete="new-password" type="' . ($keyprefix == 'search_' ? 'text' : 'password') . '" class="flat ' . $morecss . '" name="' . $keyprefix . $key . $keysuffix . '" id="' . $keyprefix . $key . $keysuffix . '" value="' . $value . '" ' . ($moreparam ? $moreparam : '') . '>';
1364
        }
1365
        if (!empty($hidden)) {
1366
            $out = '<input type="hidden" value="' . $value . '" name="' . $keyprefix . $key . $keysuffix . '" id="' . $keyprefix . $key . $keysuffix . '"/>';
1367
        }
1368
        /* Add comments
1369
          if ($type == 'date') $out.=' (YYYY-MM-DD)';
1370
          elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)';
1371
         */
1372
        return $out;
1373
    }
1374
1375
    /**
1376
     * Return HTML string to put an output field into a page
1377
     *
1378
     * @param   string	$key            		Key of attribute
1379
     * @param   string	$value          		Value to show
1380
     * @param	string	$moreparam				To add more parameters on html input tag (only checkbox use html input for output rendering)
1381
     * @param	string	$extrafieldsobjectkey	If defined (for example $object->table_element), use the new method to get extrafields data
1382
     * @return	string							Formated value
1383
     */
1384
    function showOutputField($key, $value, $moreparam = '', $extrafieldsobjectkey = '')
1385
    {
1386
        // global $conf, $langs;
1387
1388
        if (!empty($extrafieldsobjectkey)) {
1389
            $label = $this->attributes[$extrafieldsobjectkey]['label'][$key];
1390
            $type = $this->attributes[$extrafieldsobjectkey]['type'][$key];
1391
            $size = $this->attributes[$extrafieldsobjectkey]['size'][$key];
1392
            $default = $this->attributes[$extrafieldsobjectkey]['default'][$key];
1393
            $computed = $this->attributes[$extrafieldsobjectkey]['computed'][$key];
1394
            $unique = $this->attributes[$extrafieldsobjectkey]['unique'][$key];
1395
            $required = $this->attributes[$extrafieldsobjectkey]['required'][$key];
1396
            $param = $this->attributes[$extrafieldsobjectkey]['param'][$key];
1397
            $perms = dol_eval($this->attributes[$extrafieldsobjectkey]['perms'][$key], 1);
1398
            $langfile = $this->attributes[$extrafieldsobjectkey]['langfile'][$key];
1399
            $list = dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1);
1400
            $help = $this->attributes[$extrafieldsobjectkey]['help'][$key];
1401
            $hidden = (empty($list) ? 1 : 0);  // If $list empty, 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)
1402
        } else { // Old usage
1403
            $label = $this->attribute_label[$key];
1404
            $type = $this->attribute_type[$key];
1405
            $size = $this->attribute_size[$key];
1406
            $default = $this->attribute_default[$key];
1407
            $computed = $this->attribute_computed[$key];
1408
            $unique = $this->attribute_unique[$key];
1409
            $required = $this->attribute_required[$key];
1410
            $param = $this->attribute_param[$key];
1411
            $perms = dol_eval($this->attribute_perms[$key], 1);
1412
            $langfile = $this->attribute_langfile[$key];
1413
            $list = dol_eval($this->attribute_list[$key], 1);
1414
            $help = ''; // Not supported with old syntax
1415
            $hidden = (empty($list) ? 1 : 0);  // If $list empty, 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)
1416
        }
1417
1418
        if ($hidden)
1419
            return '';  // This is a protection. If field is hidden, we should just not call this method.
1420
1421
1422
1423
1424
            
1425
// If field is a computed field, value must become result of compute
1426
        if ($computed) {
1427
            // Make the eval of compute string
1428
            //var_dump($computed);
1429
            $value = dol_eval($computed, 1, 0);
1430
        }
1431
1432
        $showsize = 0;
1433
        if ($type == 'date') {
1434
            $showsize = 10;
1435
            $value = dol_print_date($value, 'day');
1436
        } elseif ($type == 'datetime') {
1437
            $showsize = 19;
1438
            $value = dol_print_date($value, 'dayhour');
1439
        } elseif ($type == 'int') {
1440
            $showsize = 10;
1441
        } elseif ($type == 'double') {
1442
            if (!empty($value)) {
1443
                $value = price($value);
1444
            }
1445
        } elseif ($type == 'boolean') {
1446
            $checked = '';
1447
            if (!empty($value)) {
1448
                $checked = ' checked ';
1449
            }
1450
            $value = '<input type="checkbox" ' . $checked . ' ' . ($moreparam ? $moreparam : '') . ' readonly disabled>';
1451
        } elseif ($type == 'mail') {
1452
            $value = dol_print_email($value, 0, 0, 0, 64, 1, 1);
1453
        } elseif ($type == 'url') {
1454
            $value = dol_print_url($value, '_blank', 32, 1);
1455
        } elseif ($type == 'phone') {
1456
            $value = dol_print_phone($value, '', 0, 0, '', '&nbsp;', 1);
1457
        } elseif ($type == 'price') {
1458
            $value = price($value, 0, Globals::$langs, 0, 0, -1, Globals::$conf->currency);
1459
        } elseif ($type == 'select') {
1460
            if ($langfile && $param['options'][$value])
1461
                $value = Globals::$langs->trans($param['options'][$value]);
1462
            else
1463
                $value = $param['options'][$value];
1464
        }
1465
        elseif ($type == 'sellist') {
1466
            $param_list = array_keys($param['options']);
1467
            $InfoFieldList = explode(":", $param_list[0]);
1468
1469
            $selectkey = "rowid";
1470
            $keyList = 'rowid';
1471
1472
            if (count($InfoFieldList) >= 3) {
1473
                $selectkey = $InfoFieldList[2];
1474
                $keyList = $InfoFieldList[2] . ' as rowid';
1475
            }
1476
1477
            $fields_label = explode('|', $InfoFieldList[1]);
1478
            if (is_array($fields_label)) {
1479
                $keyList .= ', ';
1480
                $keyList .= implode(', ', $fields_label);
1481
            }
1482
1483
            $sql = 'SELECT ' . $keyList;
1484
            $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0];
1485
            if (strpos($InfoFieldList[4], 'extra') !== false) {
1486
                $sql .= ' as main';
1487
            }
1488
            if ($selectkey == 'rowid' && empty($value)) {
1489
                $sql .= " WHERE " . $selectkey . "=0";
1490
            } elseif ($selectkey == 'rowid') {
1491
                $sql .= " WHERE " . $selectkey . "=" . Config::$dbEngine->escape($value);
1492
            } else {
1493
                $sql .= " WHERE " . $selectkey . "='" . Config::$dbEngine->escape($value) . "'";
1494
            }
1495
1496
            //$sql.= ' AND entity = '.Globals::$conf->entity;
1497
1498
            AlDolUtils::dol_syslog(get_class($this) . ':showOutputField:$type=sellist', LOG_DEBUG);
1499
            $resql = Config::$dbEngine->query($sql);
1500
            if ($resql) {
1501
                $value = ''; // value was used, so now we reste it to use it to build final output
1502
1503
                $obj = Config::$dbEngine->fetch_object($resql);
1504
1505
                // Several field into label (eq table:code|libelle:rowid)
1506
                $fields_label = explode('|', $InfoFieldList[1]);
1507
1508
                if (is_array($fields_label) && count($fields_label) > 1) {
1509
                    foreach ($fields_label as $field_toshow) {
1510
                        $translabel = '';
1511
                        if (!empty($obj->$field_toshow)) {
1512
                            $translabel = Globals::$langs->trans($obj->$field_toshow);
1513
                        }
1514
                        if ($translabel != $field_toshow) {
1515
                            $value .= dol_trunc($translabel, 18) . ' ';
1516
                        } else {
1517
                            $value .= $obj->$field_toshow . ' ';
1518
                        }
1519
                    }
1520
                } else {
1521
                    $translabel = '';
1522
                    if (!empty($obj->{$InfoFieldList[1]})) {
1523
                        $translabel = Globals::$langs->trans($obj->{$InfoFieldList[1]});
1524
                    }
1525
                    if ($translabel != $obj->{$InfoFieldList[1]}) {
1526
                        $value = dol_trunc($translabel, 18);
1527
                    } else {
1528
                        $value = $obj->{$InfoFieldList[1]};
1529
                    }
1530
                }
1531
            } else
1532
                AlDolUtils::dol_syslog(get_class($this) . '::showOutputField error ' . Config::$dbEngine->lasterror(), LOG_WARNING);
1533
        }
1534
        elseif ($type == 'radio') {
1535
            $value = $param['options'][$value];
1536
        } elseif ($type == 'checkbox') {
1537
            $value_arr = explode(',', $value);
1538
            $value = '';
1539
            $toprint = array();
1540
            if (is_array($value_arr)) {
1541
                foreach ($value_arr as $keyval => $valueval) {
1542
                    $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">' . $param['options'][$valueval] . '</li>';
1543
                }
1544
            }
1545
            $value = '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">' . implode(' ', $toprint) . '</ul></div>';
1546
        } elseif ($type == 'chkbxlst') {
1547
            $value_arr = explode(',', $value);
1548
1549
            $param_list = array_keys($param['options']);
1550
            $InfoFieldList = explode(":", $param_list[0]);
1551
1552
            $selectkey = "rowid";
1553
            $keyList = 'rowid';
1554
1555
            if (count($InfoFieldList) >= 3) {
1556
                $selectkey = $InfoFieldList[2];
1557
                $keyList = $InfoFieldList[2] . ' as rowid';
1558
            }
1559
1560
            $fields_label = explode('|', $InfoFieldList[1]);
1561
            if (is_array($fields_label)) {
1562
                $keyList .= ', ';
1563
                $keyList .= implode(', ', $fields_label);
1564
            }
1565
1566
            $sql = 'SELECT ' . $keyList;
1567
            $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0];
1568
            if (strpos($InfoFieldList[4], 'extra') !== false) {
1569
                $sql .= ' as main';
1570
            }
1571
            // $sql.= " WHERE ".$selectkey."='".Config::$dbEngine->escape($value)."'";
1572
            // $sql.= ' AND entity = '.Globals::$conf->entity;
1573
1574
            AlDolUtils::dol_syslog(get_class($this) . ':showOutputField:$type=chkbxlst', LOG_DEBUG);
1575
            $resql = Config::$dbEngine->query($sql);
1576
            if ($resql) {
1577
                $value = ''; // value was used, so now we reste it to use it to build final output
1578
                $toprint = array();
1579
                while ($obj = Config::$dbEngine->fetch_object($resql)) {
1580
1581
                    // Several field into label (eq table:code|libelle:rowid)
1582
                    $fields_label = explode('|', $InfoFieldList[1]);
1583
                    if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1584
                        if (is_array($fields_label) && count($fields_label) > 1) {
1585
                            foreach ($fields_label as $field_toshow) {
1586
                                $translabel = '';
1587
                                if (!empty($obj->$field_toshow)) {
1588
                                    $translabel = Globals::$langs->trans($obj->$field_toshow);
1589
                                }
1590
                                if ($translabel != $field_toshow) {
1591
                                    $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">' . dol_trunc($translabel, 18) . '</li>';
1592
                                } else {
1593
                                    $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">' . $obj->$field_toshow . '</li>';
1594
                                }
1595
                            }
1596
                        } else {
1597
                            $translabel = '';
1598
                            if (!empty($obj->{$InfoFieldList[1]})) {
1599
                                $translabel = Globals::$langs->trans($obj->{$InfoFieldList[1]});
1600
                            }
1601
                            if ($translabel != $obj->{$InfoFieldList[1]}) {
1602
                                $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">' . dol_trunc($translabel, 18) . '</li>';
1603
                            } else {
1604
                                $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #aaa">' . $obj->{$InfoFieldList[1]} . '</li>';
1605
                            }
1606
                        }
1607
                    }
1608
                }
1609
                $value = '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">' . implode(' ', $toprint) . '</ul></div>';
1610
            } else {
1611
                AlDolUtils::dol_syslog(get_class($this) . '::showOutputField error ' . Config::$dbEngine->lasterror(), LOG_WARNING);
1612
            }
1613
        } elseif ($type == 'link') {
1614
            $out = '';
1615
1616
            // Only if something to display (perf)
1617
            if ($value) {  // If we have -1 here, pb is into sert, not into ouptu
1618
                $param_list = array_keys($param['options']);    // $param_list='ObjectName:classPath'
1619
1620
                $InfoFieldList = explode(":", $param_list[0]);
1621
                $classname = $InfoFieldList[0];
1622
                $classpath = $InfoFieldList[1];
1623
                if (!empty($classpath)) {
1624
                    dol_include_once($InfoFieldList[1]);
1625
                    if ($classname && class_exists($classname)) {
1626
                        $object = new $classname(Config::$dbEngine);
1627
                        $object->fetch($value);
1628
                        $value = $object->getNomUrl(3);
1629
                    }
1630
                } else {
1631
                    AlDolUtils::dol_syslog('Error bad setup of extrafield', LOG_WARNING);
1632
                    return 'Error bad setup of extrafield';
1633
                }
1634
            }
1635
        } elseif ($type == 'text') {
1636
            $value = dol_htmlentitiesbr($value);
1637
        } elseif ($type == 'html') {
1638
            $value = dol_htmlentitiesbr($value);
1639
        } elseif ($type == 'password') {
1640
            $value = dol_trunc(preg_replace('/./i', '*', $value), 8, 'right', 'UTF-8', 1);
1641
        } else {
1642
            $showsize = round($size);
1643
            if ($showsize > 48)
1644
                $showsize = 48;
1645
        }
1646
1647
        //print $type.'-'.$size;
1648
        $out = $value;
1649
1650
        return $out;
1651
    }
1652
1653
    /**
1654
     * Return tag to describe alignement to use for this extrafield
1655
     *
1656
     * @param   string	$key            		Key of attribute
1657
     * @param	string	$extrafieldsobjectkey	If defined, use the new method to get extrafields data
1658
     * @return	string							Formated value
1659
     */
1660
    function getAlignFlag($key, $extrafieldsobjectkey = '')
1661
    {
1662
        // global $conf, $langs;
1663
1664
        if (!empty($extrafieldsobjectkey))
1665
            $type = $this->attributes[$extrafieldsobjectkey]['type'][$key];
1666
        else
1667
            $type = $this->attribute_type[$key];
1668
1669
        $align = '';
1670
1671
        if ($type == 'date') {
1672
            $align = "center";
1673
        } elseif ($type == 'datetime') {
1674
            $align = "center";
1675
        } elseif ($type == 'int') {
1676
            $align = "right";
1677
        } elseif ($type == 'double') {
1678
            $align = "right";
1679
        } elseif ($type == 'boolean') {
1680
            $align = "center";
1681
        } elseif ($type == 'radio') {
1682
            $align = "center";
1683
        } elseif ($type == 'checkbox') {
1684
            $align = "center";
1685
        } elseif ($type == 'price') {
1686
            $align = "right";
1687
        }
1688
1689
        return $align;
1690
    }
1691
1692
    /**
1693
     * Return HTML string to print separator extrafield
1694
     *
1695
     * @param   string	$key            Key of attribute
1696
     * @param	string	$object			Object
1697
     * @return 	string					HTML code with line for separator
1698
     */
1699
    function showSeparator($key, $object)
1700
    {
1701
        // global $langs;
1702
1703
        $out = '<tr class="trextrafieldseparator trextrafieldseparator' . $key . '"><td colspan="2"><strong>';
1704
        $out .= Globals::$langs->trans($this->attributes[$object->table_element]['label'][$key]);
0 ignored issues
show
Bug introduced by
The property table_element does not exist on string.
Loading history...
1705
        $out .= '</strong></td></tr>';
1706
        return $out;
1707
    }
1708
1709
    /**
1710
     * Fill array_options property of object by extrafields value (using for data sent by forms)
1711
     *
1712
     * @param   array	$extralabels    $array of extrafields (@deprecated)
1713
     * @param   object	$object         Object
1714
     * @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.
1715
     * @return	int						1 if array_options set, 0 if no value, -1 if error (field required missing for example)
1716
     */
1717
    function setOptionalsFromPost($extralabels, &$object, $onlykey = '')
1718
    {
1719
        // global $_POST, $langs;
1720
        $nofillrequired = ''; // For error when required field left blank
1721
        $error_field_required = array();
1722
1723
        if (is_array($this->attributes[$object->table_element]['label']))
1724
            $extralabels = $this->attributes[$object->table_element]['label'];
1725
1726
        if (is_array($extralabels)) {
1727
            // Get extra fields
1728
            foreach ($extralabels as $key => $value) {
1729
                if (!empty($onlykey) && $key != $onlykey)
1730
                    continue;
1731
1732
                $key_type = $this->attributes[$object->table_element]['type'][$key];
1733
                if ($key_type == 'separate')
1734
                    continue;
1735
1736
                $enabled = 1;
1737
                if (isset($this->attributes[$object->table_element]['list'][$key])) {
1738
                    $enabled = dol_eval($this->attributes[$object->table_element]['list'][$key], 1);
1739
                }
1740
                $perms = 1;
1741
                if (isset($this->attributes[$object->table_element]['perms'][$key])) {
1742
                    $perms = dol_eval($this->attributes[$object->table_element]['perms'][$key], 1);
1743
                }
1744
                if (empty($enabled))
1745
                    continue;
1746
                if (empty($perms))
1747
                    continue;
1748
1749
                if ($this->attributes[$object->table_element]['required'][$key]) { // Value is required
1750
                    // Check if empty without using GETPOST, value can be alpha, int, array, etc...
1751
                    if ((!is_array($_POST["options_" . $key]) && empty($_POST["options_" . $key]) && $_POST["options_" . $key] != '0') || (is_array($_POST["options_" . $key]) && empty($_POST["options_" . $key]))) {
1752
                        //print 'ccc'.$value.'-'.$this->attributes[$object->table_element]['required'][$key];
1753
                        $nofillrequired++;
1754
                        $error_field_required[] = Globals::$langs->transnoentitiesnoconv($value);
1755
                    }
1756
                }
1757
1758
                if (in_array($key_type, array('date'))) {
1759
                    // Clean parameters
1760
                    // TODO GMT date in memory must be GMT so we should add gm=true in parameters
1761
                    $value_key = dol_mktime(0, 0, 0, $_POST["options_" . $key . "month"], $_POST["options_" . $key . "day"], $_POST["options_" . $key . "year"]);
1762
                } elseif (in_array($key_type, array('datetime'))) {
1763
                    // Clean parameters
1764
                    // TODO GMT date in memory must be GMT so we should add gm=true in parameters
1765
                    $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"]);
1766
                } else if (in_array($key_type, array('checkbox', 'chkbxlst'))) {
1767
                    $value_arr = GETPOST("options_" . $key, 'array'); // check if an array
1768
                    if (!empty($value_arr)) {
1769
                        $value_key = implode($value_arr, ',');
1770
                    } else {
1771
                        $value_key = '';
1772
                    }
1773
                } else if (in_array($key_type, array('price', 'double'))) {
1774
                    $value_arr = GETPOST("options_" . $key, 'alpha');
1775
                    $value_key = price2num($value_arr);
1776
                } else {
1777
                    $value_key = GETPOST("options_" . $key);
1778
                }
1779
1780
                $object->array_options["options_" . $key] = $value_key;
1781
            }
1782
1783
            if ($nofillrequired) {
1784
                Globals::$langs->load('errors');
1785
                setEventMessages(Globals::$langs->trans('ErrorFieldsRequired') . ' : ' . implode(', ', $error_field_required), null, 'errors');
1786
                return -1;
1787
            } else {
1788
                return 1;
1789
            }
1790
        } else {
1791
            return 0;
1792
        }
1793
    }
1794
1795
    /**
1796
     * return array_options array of data of extrafields value of object sent by a search form
1797
     *
1798
     * @param  array|string		$extrafieldsobjectkey  	array of extrafields (old usage) or value of object->table_element (new usage)
1799
     * @param  string			$keyprefix      		Prefix string to add into name and id of field (can be used to avoid duplicate names)
1800
     * @param  string			$keysuffix      		Suffix string to add into name and id of field (can be used to avoid duplicate names)
1801
     * @return array|int								array_options set or 0 if no value
1802
     */
1803
    function getOptionalsFromPost($extrafieldsobjectkey, $keyprefix = '', $keysuffix = '')
1804
    {
1805
        // global $_POST;
1806
1807
        if (is_string($extrafieldsobjectkey) && is_array($this->attributes[$extrafieldsobjectkey]['label'])) {
1808
            $extralabels = $this->attributes[$extrafieldsobjectkey]['label'];
1809
        } else {
1810
            $extralabels = $extrafieldsobjectkey;
1811
        }
1812
1813
        if (is_array($extralabels)) {
1814
            $array_options = array();
1815
1816
            // Get extra fields
1817
            foreach ($extralabels as $key => $value) {
1818
                $key_type = '';
1819
                if (is_string($extrafieldsobjectkey)) {
1820
                    $key_type = $this->attributes[$extrafieldsobjectkey]['type'][$key];
1821
                }
1822
1823
                if (in_array($key_type, array('date', 'datetime'))) {
1824
                    // Clean parameters
1825
                    $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"]);
1826
                } else if (in_array($key_type, array('checkbox', 'chkbxlst'))) {
1827
                    $value_arr = GETPOST($keysuffix . "options_" . $key . $keyprefix);
1828
                    // Make sure we get an array even if there's only one checkbox
1829
                    $value_arr = (array) $value_arr;
1830
                    $value_key = implode(',', $value_arr);
1831
                } else if (in_array($key_type, array('price', 'double'))) {
1832
                    $value_arr = GETPOST($keysuffix . "options_" . $key . $keyprefix);
1833
                    $value_key = price2num($value_arr);
1834
                } else {
1835
                    $value_key = GETPOST($keysuffix . "options_" . $key . $keyprefix);
1836
                }
1837
1838
                $array_options[$keysuffix . "options_" . $key] = $value_key; // No keyprefix here. keyprefix is used only for read.
1839
            }
1840
1841
            return $array_options;
1842
        }
1843
1844
        return 0;
1845
    }
1846
}
1847