dolibarr 20.0.0
extrafields.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org>
4 * Copyright (C) 2004 Sebastien Di Cintio <sdicintio@ressource-toi.org>
5 * Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
6 * Copyright (C) 2009-2012 Laurent Destailleur <eldy@users.sourceforge.net>
7 * Copyright (C) 2009-2012 Regis Houssin <regis.houssin@inodbox.com>
8 * Copyright (C) 2013 Florian Henry <forian.henry@open-concept.pro>
9 * Copyright (C) 2015-2023 Charlene BENKE <charlene@patas-monkey.com>
10 * Copyright (C) 2016 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
11 * Copyright (C) 2017 Nicolas ZABOURI <info@inovea-conseil.com>
12 * Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
13 * Copyright (C) 2022 Antonin MARCHAL <antonin@letempledujeu.fr>
14 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program. If not, see <https://www.gnu.org/licenses/>.
28 */
29
41{
45 public $db;
46
50 public $attributes = array();
51
55 public $expand_display;
56
60 public $error = '';
61
65 public $errors = array();
66
70 public $errno;
71
75 public static $type2label = array(
76 'varchar' => 'String1Line',
77 'text' => 'TextLongNLines',
78 'html' => 'HtmlText',
79 'int' => 'Int',
80 'double' => 'Float',
81 'date' => 'Date',
82 'datetime' => 'DateAndTime',
83 //'datetimegmt'=>'DateAndTimeUTC',
84 'boolean' => 'Boolean',
85 'price' => 'ExtrafieldPrice',
86 'pricecy' => 'ExtrafieldPriceWithCurrency',
87 'phone' => 'ExtrafieldPhone',
88 'mail' => 'ExtrafieldMail',
89 'url' => 'ExtrafieldUrl',
90 'ip' => 'ExtrafieldIP',
91 'icon' => 'Icon',
92 'password' => 'ExtrafieldPassword',
93 'radio' => 'ExtrafieldRadio',
94 'select' => 'ExtrafieldSelect',
95 'sellist' => 'ExtrafieldSelectList',
96 'checkbox' => 'ExtrafieldCheckBox',
97 'chkbxlst' => 'ExtrafieldCheckBoxFromList',
98 'link' => 'ExtrafieldLink',
99 'point' => 'ExtrafieldPointGeo',
100 'multipts' => 'ExtrafieldMultiPointGeo',
101 'linestrg' => 'ExtrafieldLinestringGeo',
102 'polygon' => 'ExtrafieldPolygonGeo',
103 'separate' => 'ExtrafieldSeparator',
104 );
105
111 public function __construct($db)
112 {
113 $this->db = $db;
114 }
115
142 public 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', $totalizable = 0, $printable = 0, $moreparams = array())
143 {
144 if (empty($attrname)) {
145 return -1;
146 }
147 if (empty($label)) {
148 return -1;
149 }
150
151 $result = 0;
152
153 if ($type == 'separator' || $type == 'separate') {
154 $type = 'separate';
155 $unique = 0;
156 $required = 0;
157 } // Force unique and not required if this is a separator field to avoid troubles.
158 if ($elementtype == 'thirdparty') {
159 $elementtype = 'societe';
160 }
161 if ($elementtype == 'contact') {
162 $elementtype = 'socpeople';
163 }
164
165 // Create field into database except for separator type which is not stored in database
166 if ($type != 'separate') {
167 $result = $this->create($attrname, $type, $size, $elementtype, $unique, $required, $default_value, $param, $perms, $list, $computed, $help, $moreparams);
168 }
169 $err1 = $this->errno;
170 if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') {
171 // Add declaration of field into table
172 $result2 = $this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams);
173 $err2 = $this->errno;
174 if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) {
175 $this->error = '';
176 $this->errno = '0';
177 return 1;
178 } else {
179 return -2;
180 }
181 } else {
182 return -1;
183 }
184 }
185
212 public function updateExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique = 0, $required = 0, $default_value = '', $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0, $moreparams = array())
213 {
214 if (empty($attrname)) {
215 return -1;
216 }
217 if (empty($label)) {
218 return -1;
219 }
220
221 $result = 0;
222
223 if ($type == 'separator' || $type == 'separate') {
224 $type = 'separate';
225 $unique = 0;
226 $required = 0;
227 } // Force unique and not required if this is a separator field to avoid troubles.
228 if ($elementtype == 'thirdparty') {
229 $elementtype = 'societe';
230 }
231 if ($elementtype == 'contact') {
232 $elementtype = 'socpeople';
233 }
234
235 // Create field into database except for separator type which is not stored in database
236 if ($type != 'separate') {
237 dol_syslog(get_class($this).'::thisupdate', LOG_DEBUG);
238 $result = $this->update($attrname, $label, $type, $size, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams);
239 }
240 $err1 = $this->errno;
241 if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') {
242 // Add declaration of field into table
243 dol_syslog(get_class($this).'::thislabel', LOG_DEBUG);
244 $result2 = $this->update_label($attrname, $label, $type, $size, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams);
245 $err2 = $this->errno;
246 if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) {
247 $this->error = '';
248 $this->errno = '0';
249 return 1;
250 } else {
251 return -2;
252 }
253 } else {
254 return -1;
255 }
256 }
257
277 private function create($attrname, $type = 'varchar', $length = '255', $elementtype = '', $unique = 0, $required = 0, $default_value = '', $param = array(), $perms = '', $list = '0', $computed = '', $help = '', $moreparams = array())
278 {
279 if ($elementtype == 'thirdparty') {
280 $elementtype = 'societe';
281 }
282 if ($elementtype == 'contact') {
283 $elementtype = 'socpeople';
284 }
285
286 $table = $elementtype.'_extrafields';
287 if ($elementtype == 'categorie') {
288 $table = 'categories_extrafields';
289 }
290
291 if (!empty($attrname) && preg_match("/^\w[a-zA-Z0-9_]*$/", $attrname) && !is_numeric($attrname)) {
292 if ($type == 'boolean') {
293 $typedb = 'int';
294 $lengthdb = '1';
295 } elseif ($type == 'price') {
296 $typedb = 'double';
297 $lengthdb = '24,8';
298 } elseif ($type == 'pricecy') {
299 $typedb = 'varchar';
300 $lengthdb = '64';
301 } elseif ($type == 'phone') {
302 $typedb = 'varchar';
303 $lengthdb = '20';
304 } elseif ($type == 'mail' || $type == 'ip' || $type == 'icon') {
305 $typedb = 'varchar';
306 $lengthdb = '128';
307 } elseif ($type == 'url') {
308 $typedb = 'varchar';
309 $lengthdb = '255';
310 } elseif (($type == 'select') || ($type == 'sellist') || ($type == 'radio') || ($type == 'checkbox') || ($type == 'chkbxlst')) {
311 $typedb = 'varchar';
312 $lengthdb = '255';
313 } elseif ($type == 'link') {
314 $typedb = 'int';
315 $lengthdb = '11';
316 } elseif ($type == 'point') {
317 $typedb = 'point';
318 $lengthdb = '';
319 } elseif ($type == 'multipts') {
320 $typedb = 'multipoint';
321 $lengthdb = '';
322 } elseif ($type == 'linestrg') {
323 $typedb = 'linestring';
324 $lengthdb = '';
325 } elseif ($type == 'polygon') {
326 $typedb = 'polygon';
327 $lengthdb = '';
328 } elseif ($type == 'html') {
329 $typedb = 'text';
330 $lengthdb = $length;
331 } elseif ($type == 'password') {
332 $typedb = 'varchar';
333 $lengthdb = '128';
334 } else {
335 $typedb = $type;
336 $lengthdb = $length;
337 if ($type == 'varchar' && empty($lengthdb)) {
338 $lengthdb = '255';
339 }
340 }
341 $field_desc = array(
342 'type' => $typedb,
343 'value' => $lengthdb,
344 'null' => ($required ? 'NOT NULL' : 'NULL'),
345 'default' => $default_value
346 );
347
348 $result = $this->db->DDLAddField($this->db->prefix().$table, $attrname, $field_desc);
349 if ($result > 0) {
350 if ($unique) {
351 $sql = "ALTER TABLE ".$this->db->prefix().$table." ADD UNIQUE INDEX uk_".$table."_".$attrname." (".$attrname.")";
352 $resql = $this->db->query($sql, 1, 'dml');
353 }
354 return 1;
355 } else {
356 $this->error = $this->db->lasterror();
357 $this->errno = $this->db->lasterrno();
358 return -1;
359 }
360 } else {
361 return 0;
362 }
363 }
364
365 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
393 private function create_label($attrname, $label = '', $type = '', $pos = 0, $size = '', $elementtype = '', $unique = 0, $required = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0, $moreparams = array())
394 {
395 // phpcs:enable
396 global $conf, $user;
397
398 if ($elementtype == 'thirdparty') {
399 $elementtype = 'societe';
400 }
401 if ($elementtype == 'contact') {
402 $elementtype = 'socpeople';
403 }
404
405 // Clean parameters
406 if (empty($pos)) {
407 $pos = 0;
408 }
409 if (empty($list)) {
410 $list = '0';
411 }
412 if (empty($required)) {
413 $required = 0;
414 }
415 if (empty($unique)) {
416 $unique = 0;
417 }
418 if (empty($printable)) {
419 $printable = 0;
420 }
421 if (empty($alwayseditable)) {
422 $alwayseditable = 0;
423 }
424 if (empty($totalizable)) {
425 $totalizable = 0;
426 }
427
428 $css = '';
429 if (!empty($moreparams) && !empty($moreparams['css'])) {
430 $css = $moreparams['css'];
431 }
432 $csslist = '';
433 if (!empty($moreparams) && !empty($moreparams['csslist'])) {
434 $csslist = $moreparams['csslist'];
435 }
436 $cssview = '';
437 if (!empty($moreparams) && !empty($moreparams['cssview'])) {
438 $cssview = $moreparams['cssview'];
439 }
440
441 if (!empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/", $attrname) && !is_numeric($attrname)) {
442 if (is_array($param) && count($param) > 0) {
443 $params = serialize($param);
444 } elseif (strlen($param) > 0) {
445 $params = trim($param);
446 } else {
447 $params = '';
448 }
449
450 $sql = "INSERT INTO ".$this->db->prefix()."extrafields(";
451 $sql .= " name,";
452 $sql .= " label,";
453 $sql .= " type,";
454 $sql .= " pos,";
455 $sql .= " size,";
456 $sql .= " entity,";
457 $sql .= " elementtype,";
458 $sql .= " fieldunique,";
459 $sql .= " fieldrequired,";
460 $sql .= " param,";
461 $sql .= " alwayseditable,";
462 $sql .= " perms,";
463 $sql .= " langs,";
464 $sql .= " list,";
465 $sql .= " printable,";
466 $sql .= " fielddefault,";
467 $sql .= " fieldcomputed,";
468 $sql .= " fk_user_author,";
469 $sql .= " fk_user_modif,";
470 $sql .= " datec,";
471 $sql .= " enabled,";
472 $sql .= " help,";
473 $sql .= " totalizable,";
474 $sql .= " css,";
475 $sql .= " csslist,";
476 $sql .= " cssview";
477 $sql .= " )";
478 $sql .= " VALUES('".$this->db->escape($attrname)."',";
479 $sql .= " '".$this->db->escape($label)."',";
480 $sql .= " '".$this->db->escape($type)."',";
481 $sql .= " ".((int) $pos).",";
482 $sql .= " '".$this->db->escape($size)."',";
483 $sql .= " ".($entity === '' ? $conf->entity : $entity).",";
484 $sql .= " '".$this->db->escape($elementtype)."',";
485 $sql .= " ".((int) $unique).",";
486 $sql .= " ".((int) $required).",";
487 $sql .= " '".$this->db->escape($params)."',";
488 $sql .= " ".((int) $alwayseditable).",";
489 $sql .= " ".($perms ? "'".$this->db->escape($perms)."'" : "null").",";
490 $sql .= " ".($langfile ? "'".$this->db->escape($langfile)."'" : "null").",";
491 $sql .= " '".$this->db->escape($list)."',";
492 $sql .= " '".$this->db->escape($printable)."',";
493 $sql .= " ".($default ? "'".$this->db->escape($default)."'" : "null").",";
494 $sql .= " ".($computed ? "'".$this->db->escape($computed)."'" : "null").",";
495 $sql .= " ".(is_object($user) ? $user->id : 0).",";
496 $sql .= " ".(is_object($user) ? $user->id : 0).",";
497 $sql .= "'".$this->db->idate(dol_now())."',";
498 $sql .= " ".($enabled ? "'".$this->db->escape($enabled)."'" : "1").",";
499 $sql .= " ".($help ? "'".$this->db->escape($help)."'" : "null").",";
500 $sql .= " ".($totalizable ? 'TRUE' : 'FALSE').",";
501 $sql .= " ".($css ? "'".$this->db->escape($css)."'" : "null").",";
502 $sql .= " ".($csslist ? "'".$this->db->escape($csslist)."'" : "null").",";
503 $sql .= " ".($cssview ? "'".$this->db->escape($cssview)."'" : "null");
504 $sql .= ')';
505
506 if ($this->db->query($sql)) {
507 dol_syslog(get_class($this)."::create_label_success", LOG_DEBUG);
508 return 1;
509 } else {
510 dol_syslog(get_class($this)."::create_label_error", LOG_DEBUG);
511 $this->error = $this->db->lasterror();
512 $this->errno = $this->db->lasterrno();
513 return -1;
514 }
515 }
516 return -1;
517 }
518
526 public function delete($attrname, $elementtype = '')
527 {
528 if ($elementtype == 'thirdparty') {
529 $elementtype = 'societe';
530 }
531 if ($elementtype == 'contact') {
532 $elementtype = 'socpeople';
533 }
534
535 $table = $elementtype.'_extrafields';
536 if ($elementtype == 'categorie') {
537 $table = 'categories_extrafields';
538 }
539
540 $error = 0;
541
542 if (!empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/", $attrname)) {
543 $result = $this->delete_label($attrname, $elementtype);
544 if ($result < 0) {
545 $this->error = $this->db->lasterror();
546 $this->errors[] = $this->db->lasterror();
547 $error++;
548 }
549
550 if (!$error) {
551 $sql = "SELECT COUNT(rowid) as nb";
552 $sql .= " FROM ".$this->db->prefix()."extrafields";
553 $sql .= " WHERE elementtype = '".$this->db->escape($elementtype)."'";
554 $sql .= " AND name = '".$this->db->escape($attrname)."'";
555 //$sql.= " AND entity IN (0,".$conf->entity.")"; Do not test on entity here. We want to see if there is still on field remaining in other entities before deleting field in table
556 $resql = $this->db->query($sql);
557 if ($resql) {
558 $obj = $this->db->fetch_object($resql);
559 if ($obj->nb <= 0) {
560 $result = $this->db->DDLDropField($this->db->prefix().$table, $attrname); // This also drop the unique key
561 if ($result < 0) {
562 $this->error = $this->db->lasterror();
563 $this->errors[] = $this->db->lasterror();
564 $error++;
565 }
566 }
567 }
568 }
569
570 return $result;
571 } else {
572 return 0;
573 }
574 }
575
576 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
584 private function delete_label($attrname, $elementtype = '')
585 {
586 // phpcs:enable
587 global $conf;
588
589 if ($elementtype == 'thirdparty') {
590 $elementtype = 'societe';
591 }
592 if ($elementtype == 'contact') {
593 $elementtype = 'socpeople';
594 }
595
596 if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/", $attrname)) {
597 $sql = "DELETE FROM ".$this->db->prefix()."extrafields";
598 $sql .= " WHERE name = '".$this->db->escape($attrname)."'";
599 $sql .= " AND entity IN (0,".$conf->entity.')';
600 $sql .= " AND elementtype = '".$this->db->escape($elementtype)."'";
601
602 dol_syslog(get_class($this)."::delete_label", LOG_DEBUG);
603 $resql = $this->db->query($sql);
604 if ($resql) {
605 return 1;
606 } else {
607 dol_print_error($this->db);
608 return -1;
609 }
610 } else {
611 return 0;
612 }
613 }
614
642 public function update($attrname, $label, $type, $length, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = array(), $alwayseditable = 0, $perms = '', $list = '', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0, $moreparams = array())
643 {
644 global $action, $hookmanager;
645
646 if ($elementtype == 'thirdparty') {
647 $elementtype = 'societe';
648 }
649 if ($elementtype == 'contact') {
650 $elementtype = 'socpeople';
651 }
652
653 $table = $elementtype.'_extrafields';
654 if ($elementtype == 'categorie') {
655 $table = 'categories_extrafields';
656 }
657
658 if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/", $attrname)) {
659 if ($type == 'boolean') {
660 $typedb = 'int';
661 $lengthdb = '1';
662 } elseif ($type == 'price') {
663 $typedb = 'double';
664 $lengthdb = '24,8';
665 } elseif ($type == 'pricecy') {
666 $typedb = 'varchar';
667 $lengthdb = '64';
668 } elseif ($type == 'phone') {
669 $typedb = 'varchar';
670 $lengthdb = '20';
671 } elseif ($type == 'mail' || $type == 'ip' || $type == 'icon') {
672 $typedb = 'varchar';
673 $lengthdb = '128';
674 } elseif ($type == 'url') {
675 $typedb = 'varchar';
676 $lengthdb = '255';
677 } elseif (($type == 'select') || ($type == 'sellist') || ($type == 'radio') || ($type == 'checkbox') || ($type == 'chkbxlst')) {
678 $typedb = 'varchar';
679 $lengthdb = '255';
680 } elseif ($type == 'html') {
681 $typedb = 'text';
682 $lengthdb = $length;
683 } elseif ($type == 'link') {
684 $typedb = 'int';
685 $lengthdb = '11';
686 } elseif ($type == 'point') {
687 $typedb = 'point';
688 $lengthdb = '';
689 } elseif ($type == 'multipts') {
690 $typedb = 'multipoint';
691 $lengthdb = '';
692 } elseif ($type == 'linestrg') {
693 $typedb = 'linestring';
694 $lengthdb = '';
695 } elseif ($type == 'polygon') {
696 $typedb = 'polygon';
697 $lengthdb = '';
698 } elseif ($type == 'password') {
699 $typedb = 'varchar';
700 $lengthdb = '128';
701 } else {
702 $typedb = $type;
703 $lengthdb = $length;
704 }
705 $field_desc = array('type' => $typedb, 'value' => $lengthdb, 'null' => ($required ? 'NOT NULL' : 'NULL'), 'default' => $default);
706
707 if (is_object($hookmanager)) {
708 $hookmanager->initHooks(array('extrafieldsdao'));
709 $parameters = array('field_desc' => &$field_desc, 'table' => $table, 'attr_name' => $attrname, 'label' => $label, 'type' => $type, 'length' => $length, 'unique' => $unique, 'required' => $required, 'pos' => $pos, 'param' => $param, 'alwayseditable' => $alwayseditable, 'perms' => $perms, 'list' => $list, 'help' => $help, 'default' => $default, 'computed' => $computed, 'entity' => $entity, 'langfile' => $langfile, 'enabled' => $enabled, 'totalizable' => $totalizable, 'printable' => $printable);
710 $reshook = $hookmanager->executeHooks('updateExtrafields', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
711
712 if ($reshook < 0) {
713 $this->error = $this->db->lasterror();
714 return -1;
715 }
716 }
717
718 dol_syslog(get_class($this).'::DDLUpdateField', LOG_DEBUG);
719 if ($type != 'separate') { // No table update when separate type
720 $result = $this->db->DDLUpdateField($this->db->prefix().$table, $attrname, $field_desc);
721 }
722 if ($result > 0 || $type == 'separate') {
723 if ($label) {
724 dol_syslog(get_class($this).'::update_label', LOG_DEBUG);
725 $result = $this->update_label($attrname, $label, $type, $length, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams);
726 }
727 if ($result > 0) {
728 $sql = '';
729 if ($unique) {
730 dol_syslog(get_class($this).'::update_unique', LOG_DEBUG);
731 $sql = "ALTER TABLE ".$this->db->prefix().$table." ADD UNIQUE INDEX uk_".$table."_".$this->db->sanitize($attrname)." (".$this->db->sanitize($attrname).")";
732 } else {
733 dol_syslog(get_class($this).'::update_common', LOG_DEBUG);
734 $sql = "ALTER TABLE ".$this->db->prefix().$table." DROP INDEX IF EXISTS uk_".$table."_".$this->db->sanitize($attrname);
735 }
736 dol_syslog(get_class($this).'::update', LOG_DEBUG);
737 $resql = $this->db->query($sql, 1, 'dml');
738 /*if ($resql < 0) {
739 $this->error = $this->db->lasterror();
740 return -1;
741 }*/
742 return 1;
743 } else {
744 $this->error = $this->db->lasterror();
745 return -1;
746 }
747 } else {
748 $this->error = $this->db->lasterror();
749 return -1;
750 }
751 } else {
752 return 0;
753 }
754 }
755
756 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
785 private function update_label($attrname, $label, $type, $size, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = array(), $alwayseditable = 0, $perms = '', $list = '0', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0, $moreparams = array())
786 {
787 // phpcs:enable
788 global $conf, $user;
789 dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled.", ".$totalizable.", ".$printable);
790
791 // Clean parameters
792 if ($elementtype == 'thirdparty') {
793 $elementtype = 'societe';
794 }
795 if ($elementtype == 'contact') {
796 $elementtype = 'socpeople';
797 }
798
799 if (empty($pos)) {
800 $pos = 0;
801 }
802 if (empty($list)) {
803 $list = '0';
804 }
805 if (empty($totalizable)) {
806 $totalizable = 0;
807 }
808 if (empty($required)) {
809 $required = 0;
810 }
811 if (empty($unique)) {
812 $unique = 0;
813 }
814 if (empty($alwayseditable)) {
815 $alwayseditable = 0;
816 }
817
818 $css = '';
819 if (!empty($moreparams) && !empty($moreparams['css'])) {
820 $css = $moreparams['css'];
821 }
822 $csslist = '';
823 if (!empty($moreparams) && !empty($moreparams['csslist'])) {
824 $csslist = $moreparams['csslist'];
825 }
826 $cssview = '';
827 if (!empty($moreparams) && !empty($moreparams['cssview'])) {
828 $cssview = $moreparams['cssview'];
829 }
830
831 if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/", $attrname)) {
832 $this->db->begin();
833
834 if (is_array($param) && count($param) > 0) {
835 $params = serialize($param);
836 } elseif (is_array($param)) {
837 $params = '';
838 } elseif (strlen($param) > 0) {
839 $params = trim($param);
840 } else {
841 $params = '';
842 }
843
844 if ($entity === '' || $entity != '0') {
845 // We don't want on all entities, we delete all and current
846 $sql_del = "DELETE FROM ".$this->db->prefix()."extrafields";
847 $sql_del .= " WHERE name = '".$this->db->escape($attrname)."'";
848 $sql_del .= " AND entity IN (0, ".($entity === '' ? $conf->entity : $entity).")";
849 $sql_del .= " AND elementtype = '".$this->db->escape($elementtype)."'";
850 } else {
851 // We want on all entities ($entities = '0'), we delete on all only (we keep setup specific to each entity)
852 $sql_del = "DELETE FROM ".$this->db->prefix()."extrafields";
853 $sql_del .= " WHERE name = '".$this->db->escape($attrname)."'";
854 $sql_del .= " AND entity = 0";
855 $sql_del .= " AND elementtype = '".$this->db->escape($elementtype)."'";
856 }
857 $resql1 = $this->db->query($sql_del);
858
859 $sql = "INSERT INTO ".$this->db->prefix()."extrafields(";
860 $sql .= " name,"; // This is code
861 $sql .= " entity,";
862 $sql .= " label,";
863 $sql .= " type,";
864 $sql .= " size,";
865 $sql .= " elementtype,";
866 $sql .= " fieldunique,";
867 $sql .= " fieldrequired,";
868 $sql .= " perms,";
869 $sql .= " langs,";
870 $sql .= " pos,";
871 $sql .= " alwayseditable,";
872 $sql .= " param,";
873 $sql .= " list,";
874 $sql .= " printable,";
875 $sql .= " totalizable,";
876 $sql .= " fielddefault,";
877 $sql .= " fieldcomputed,";
878 $sql .= " fk_user_author,";
879 $sql .= " fk_user_modif,";
880 $sql .= " datec,";
881 $sql .= " enabled,";
882 $sql .= " help,";
883 $sql .= " css,";
884 $sql .= " csslist,";
885 $sql .= " cssview";
886 $sql .= ") VALUES (";
887 $sql .= "'".$this->db->escape($attrname)."',";
888 $sql .= " ".($entity === '' ? $conf->entity : $entity).",";
889 $sql .= " '".$this->db->escape($label)."',";
890 $sql .= " '".$this->db->escape($type)."',";
891 $sql .= " '".$this->db->escape($size)."',";
892 $sql .= " '".$this->db->escape($elementtype)."',";
893 $sql .= " ".$unique.",";
894 $sql .= " ".$required.",";
895 $sql .= " ".($perms ? "'".$this->db->escape($perms)."'" : "null").",";
896 $sql .= " ".($langfile ? "'".$this->db->escape($langfile)."'" : "null").",";
897 $sql .= " ".$pos.",";
898 $sql .= " '".$this->db->escape($alwayseditable)."',";
899 $sql .= " '".$this->db->escape($params)."',";
900 $sql .= " '".$this->db->escape($list)."',";
901 $sql .= " ".((int) $printable).",";
902 $sql .= " ".($totalizable ? 'TRUE' : 'FALSE').",";
903 $sql .= " ".(($default != '') ? "'".$this->db->escape($default)."'" : "null").",";
904 $sql .= " ".($computed ? "'".$this->db->escape($computed)."'" : "null").",";
905 $sql .= " ".$user->id.",";
906 $sql .= " ".$user->id.",";
907 $sql .= "'".$this->db->idate(dol_now())."',";
908 $sql .= "'".$this->db->escape($enabled)."',";
909 $sql .= " ".($help ? "'".$this->db->escape($help)."'" : "null").",";
910 $sql .= " ".($css ? "'".$this->db->escape($css)."'" : "null").",";
911 $sql .= " ".($csslist ? "'".$this->db->escape($csslist)."'" : "null").",";
912 $sql .= " ".($cssview ? "'".$this->db->escape($cssview)."'" : "null");
913 $sql .= ")";
914
915 $resql2 = $this->db->query($sql);
916
917 if ($resql1 && $resql2) {
918 $this->db->commit();
919 return 1;
920 } else {
921 $this->db->rollback();
922 dol_print_error($this->db);
923 return -1;
924 }
925 } else {
926 return 0;
927 }
928 }
929
930 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
939 public function fetch_name_optionals_label($elementtype, $forceload = false, $attrname = '')
940 {
941 // phpcs:enable
942 global $conf;
943
944 if (empty($elementtype)) {
945 return array();
946 }
947
948 if ($elementtype == 'thirdparty') {
949 $elementtype = 'societe';
950 }
951 if ($elementtype == 'contact') {
952 $elementtype = 'socpeople';
953 }
954 if ($elementtype == 'order_supplier') {
955 $elementtype = 'commande_fournisseur';
956 }
957
958 // Test cache $this->attributes[$elementtype]['loaded'] to see if we must do something
959 // TODO
960
961 $array_name_label = array();
962
963 // We should not have several time this request. If we have, there is some optimization to do by calling a simple $extrafields->fetch_optionals() in top of code and not into subcode
964 $sql = "SELECT rowid, name, label, type, size, elementtype, fieldunique, fieldrequired, param, pos, alwayseditable, perms, langs, list, printable, totalizable, fielddefault, fieldcomputed, entity, enabled, help,";
965 $sql .= " css, cssview, csslist";
966 $sql .= " FROM ".$this->db->prefix()."extrafields";
967 //$sql.= " WHERE entity IN (0,".$conf->entity.")"; // Filter is done later
968 if ($elementtype && $elementtype != 'all') {
969 $sql .= " WHERE elementtype = '".$this->db->escape($elementtype)."'"; // Filed with object->table_element
970 }
971 if ($attrname && $elementtype && $elementtype != 'all') {
972 $sql .= " AND name = '".$this->db->escape($attrname)."'";
973 }
974 $sql .= " ORDER BY pos";
975
976 $resql = $this->db->query($sql);
977 if ($resql) {
978 $count = 0;
979 if ($this->db->num_rows($resql)) {
980 while ($tab = $this->db->fetch_object($resql)) {
981 if ($tab->entity != 0 && $tab->entity != $conf->entity) {
982 // This field is not in current entity. We discard but before we save it into the array of mandatory fields if it is a mandatory field without default value
983 if ($tab->fieldrequired && is_null($tab->fielddefault)) {
984 $this->attributes[$tab->elementtype]['mandatoryfieldsofotherentities'][$tab->name] = $tab->type;
985 }
986 continue;
987 }
988
989 // We can add this attribute to object. TODO Remove this and return $this->attributes[$elementtype]['label']
990 if ($tab->type != 'separate') {
991 $array_name_label[$tab->name] = $tab->label;
992 }
993
994
995 $this->attributes[$tab->elementtype]['type'][$tab->name] = $tab->type;
996 $this->attributes[$tab->elementtype]['label'][$tab->name] = $tab->label;
997 $this->attributes[$tab->elementtype]['size'][$tab->name] = $tab->size;
998 $this->attributes[$tab->elementtype]['elementtype'][$tab->name] = $tab->elementtype;
999 $this->attributes[$tab->elementtype]['default'][$tab->name] = $tab->fielddefault;
1000 $this->attributes[$tab->elementtype]['computed'][$tab->name] = $tab->fieldcomputed;
1001 $this->attributes[$tab->elementtype]['unique'][$tab->name] = $tab->fieldunique;
1002 $this->attributes[$tab->elementtype]['required'][$tab->name] = $tab->fieldrequired;
1003 $this->attributes[$tab->elementtype]['param'][$tab->name] = ($tab->param ? jsonOrUnserialize($tab->param) : '');
1004 $this->attributes[$tab->elementtype]['pos'][$tab->name] = $tab->pos;
1005 $this->attributes[$tab->elementtype]['alwayseditable'][$tab->name] = $tab->alwayseditable;
1006 $this->attributes[$tab->elementtype]['perms'][$tab->name] = ((is_null($tab->perms) || strlen($tab->perms) == 0) ? 1 : $tab->perms);
1007 $this->attributes[$tab->elementtype]['langfile'][$tab->name] = $tab->langs;
1008 $this->attributes[$tab->elementtype]['list'][$tab->name] = $tab->list;
1009 $this->attributes[$tab->elementtype]['printable'][$tab->name] = $tab->printable;
1010 $this->attributes[$tab->elementtype]['totalizable'][$tab->name] = ($tab->totalizable ? 1 : 0);
1011 $this->attributes[$tab->elementtype]['entityid'][$tab->name] = $tab->entity;
1012 $this->attributes[$tab->elementtype]['enabled'][$tab->name] = $tab->enabled;
1013 $this->attributes[$tab->elementtype]['help'][$tab->name] = $tab->help;
1014 $this->attributes[$tab->elementtype]['css'][$tab->name] = $tab->css;
1015 $this->attributes[$tab->elementtype]['cssview'][$tab->name] = $tab->cssview;
1016 $this->attributes[$tab->elementtype]['csslist'][$tab->name] = $tab->csslist;
1017
1018 $this->attributes[$tab->elementtype]['loaded'] = 1;
1019 $count++;
1020 }
1021 }
1022 if ($elementtype) {
1023 $this->attributes[$elementtype]['loaded'] = 1; // Note: If nothing is found, we also set the key 'loaded' to 1.
1024 $this->attributes[$elementtype]['count'] = $count;
1025 }
1026 } else {
1027 $this->error = $this->db->lasterror();
1028 dol_syslog(get_class($this)."::fetch_name_optionals_label ".$this->error, LOG_ERR);
1029 }
1030
1031 return $array_name_label;
1032 }
1033
1034
1050 public function showInputField($key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '', $objectid = 0, $extrafieldsobjectkey = '', $mode = 0)
1051 {
1052 global $conf, $langs, $form;
1053
1054 if (!is_object($form)) {
1055 require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
1056 $form = new Form($this->db);
1057 }
1058
1059 $out = '';
1060
1061 if (!preg_match('/options_$/', $keyprefix)) { // Because we work on extrafields, we add 'options_' to prefix if not already added
1062 $keyprefix = $keyprefix.'options_';
1063 }
1064
1065 if (empty($extrafieldsobjectkey)) {
1066 dol_syslog(get_class($this).'::showInputField extrafieldsobjectkey required', LOG_ERR);
1067 return 'BadValueForParamExtraFieldsObjectKey';
1068 }
1069
1070 $label = $this->attributes[$extrafieldsobjectkey]['label'][$key];
1071 $type = $this->attributes[$extrafieldsobjectkey]['type'][$key];
1072 $size = $this->attributes[$extrafieldsobjectkey]['size'][$key];
1073 $default = $this->attributes[$extrafieldsobjectkey]['default'][$key];
1074 $computed = $this->attributes[$extrafieldsobjectkey]['computed'][$key];
1075 $unique = $this->attributes[$extrafieldsobjectkey]['unique'][$key];
1076 $required = $this->attributes[$extrafieldsobjectkey]['required'][$key];
1077 $param = $this->attributes[$extrafieldsobjectkey]['param'][$key];
1078 $perms = (int) dol_eval($this->attributes[$extrafieldsobjectkey]['perms'][$key], 1, 1, '2');
1079 $langfile = $this->attributes[$extrafieldsobjectkey]['langfile'][$key];
1080 $list = (string) dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1, 1, '2');
1081 $totalizable = $this->attributes[$extrafieldsobjectkey]['totalizable'][$key];
1082 $help = $this->attributes[$extrafieldsobjectkey]['help'][$key];
1083 $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)
1084
1085 //var_dump('key='.$key.' '.$value.' '.$moreparam.' '.$keysuffix.' '.$keyprefix.' '.$objectid.' '.$extrafieldsobjectkey.' '.$mode);
1086 //var_dump('label='.$label.' type='.$type.' param='.var_export($param, 1));
1087
1088 if ($computed) {
1089 if (!preg_match('/^search_/', $keyprefix)) {
1090 return '<span class="opacitymedium">'.$langs->trans("AutomaticallyCalculated").'</span>';
1091 } else {
1092 return '';
1093 }
1094 }
1095
1096 //
1097 // 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200'
1098 if (empty($morecss)) {
1099 // Add automatic css
1100 if ($type == 'date') {
1101 $morecss = 'minwidth100imp';
1102 } elseif ($type == 'datetime' || $type == 'datetimegmt' || $type == 'link') {
1103 $morecss = 'minwidth200imp';
1104 } elseif (in_array($type, array('int', 'integer', 'double', 'price'))) {
1105 $morecss = 'maxwidth75';
1106 } elseif ($type == 'password') {
1107 $morecss = 'maxwidth100';
1108 } elseif ($type == 'url') {
1109 $morecss = 'minwidth400';
1110 } elseif ($type == 'boolean') {
1111 $morecss = '';
1112 } elseif ($type == 'radio') {
1113 $morecss = 'width25';
1114 } else {
1115 if (empty($size) || round((float) $size) < 12) {
1116 $morecss = 'minwidth100';
1117 } elseif (round((float) $size) <= 48) {
1118 $morecss = 'minwidth200';
1119 } else {
1120 $morecss = 'minwidth400';
1121 }
1122 }
1123 // If css forced in attribute, we use this one
1124 if (!empty($this->attributes[$extrafieldsobjectkey]['css'][$key])) {
1125 $morecss = $this->attributes[$extrafieldsobjectkey]['css'][$key];
1126 }
1127 }
1128
1129 if (in_array($type, array('date'))) {
1130 $tmp = explode(',', $size);
1131 $newsize = $tmp[0];
1132 $showtime = 0;
1133
1134 // Do not show current date when field not required (see selectDate() method)
1135 if (!$required && $value == '') {
1136 $value = '-1';
1137 }
1138
1139 if ($mode == 1) {
1140 // search filter on a date extrafield shows two inputs to select a date range
1141 $prefill = array(
1142 'start' => isset($value['start']) ? $value['start'] : '',
1143 'end' => isset($value['end']) ? $value['end'] : ''
1144 );
1145 $out = '<div ' . ($moreparam ? $moreparam : '') . '><div class="nowrap">';
1146 $out .= $form->selectDate($prefill['start'], $keyprefix.$key.$keysuffix.'_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"));
1147 $out .= '</div><div class="nowrap">';
1148 $out .= $form->selectDate($prefill['end'], $keyprefix.$key.$keysuffix.'_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
1149 $out .= '</div></div>';
1150 } else {
1151 // TODO Must also support $moreparam
1152 $out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1);
1153 }
1154 } elseif (in_array($type, array('datetime', 'datetimegmt'))) {
1155 $tmp = explode(',', $size);
1156 $newsize = $tmp[0];
1157 $showtime = 1;
1158
1159 // Do not show current date when field not required (see selectDate() method)
1160 if (!$required && $value == '') {
1161 $value = '-1';
1162 }
1163
1164 if ($mode == 1) {
1165 // search filter on a date extrafield shows two inputs to select a date range
1166 $prefill = array(
1167 'start' => isset($value['start']) ? $value['start'] : '',
1168 'end' => isset($value['end']) ? $value['end'] : ''
1169 );
1170 $out = '<div ' . ($moreparam ? $moreparam : '') . '><div class="nowrap">';
1171 $out .= $form->selectDate($prefill['start'], $keyprefix.$key.$keysuffix.'_start', 1, 1, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"), 'tzuserrel');
1172 $out .= '</div><div class="nowrap">';
1173 $out .= $form->selectDate($prefill['end'], $keyprefix.$key.$keysuffix.'_end', 1, 1, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"), 'tzuserrel');
1174 $out .= '</div></div>';
1175 } else {
1176 // TODO Must also support $moreparam
1177 $out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1, '', '', '', 1, '', '', 'tzuserrel');
1178 }
1179 } elseif (in_array($type, array('int', 'integer'))) {
1180 $tmp = explode(',', $size);
1181 $newsize = $tmp[0];
1182 $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 : '').'>';
1183 } elseif (preg_match('/varchar/', $type)) {
1184 $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 : '').'>';
1185 } elseif (in_array($type, array('mail', 'ip', 'phone', 'url'))) {
1186 $out = '<input type="text" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam ? $moreparam : '').'>';
1187 } elseif ($type == 'icon') {
1188 /* External lib inclusion are not allowed in backoffice. Also lib is included several time if there is several icon file.
1189 Some code must be added into main when MAIN_ADD_ICONPICKER_JS is set to add of lib in html header
1190 $out ='<link rel="stylesheet" href="'.dol_buildpath('/myfield/css/fontawesome-iconpicker.min.css', 1).'">';
1191 $out.='<script src="'.dol_buildpath('/myfield/js/fontawesome-iconpicker.min.js', 1).'"></script>';
1192 */
1193 $out .= '<input type="text" class="form-control icp icp-auto iconpicker-element iconpicker-input flat '.$morecss.' maxwidthonsmartphone"';
1194 $out .= ' name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam ? $moreparam : '').'>';
1195 if (getDolGlobalInt('MAIN_ADD_ICONPICKER_JS')) {
1196 $out .= '<script>';
1197 $options = "{ title: '<b>".$langs->trans("IconFieldSelector")."</b>', placement: 'right', showFooter: false, templates: {";
1198 $options .= "iconpicker: '<div class=\"iconpicker\"><div style=\"background-color:#EFEFEF;\" class=\"iconpicker-items\"></div></div>',";
1199 $options .= "iconpickerItem: '<a role=\"button\" href=\"#\" class=\"iconpicker-item\" style=\"background-color:#DDDDDD;\"><i></i></a>',";
1200 // $options.="buttons: '<button style=\"background-color:#FFFFFF;\" class=\"iconpicker-btn iconpicker-btn-cancel btn btn-default btn-sm\">".$langs->trans("Cancel")."</button>";
1201 // $options.="<button style=\"background-color:#FFFFFF;\" class=\"iconpicker-btn iconpicker-btn-accept btn btn-primary btn-sm\">".$langs->trans("Save")."</button>',";
1202 $options .= "footer: '<div class=\"popover-footer\" style=\"background-color:#EFEFEF;\"></div>',";
1203 $options .= "search: '<input type=\"search\" class\"form-control iconpicker-search\" placeholder=\"".$langs->trans("TypeToFilter")."\" />',";
1204 $options .= "popover: '<div class=\"iconpicker-popover popover\">";
1205 $options .= " <div class=\"arrow\" ></div>";
1206 $options .= " <div class=\"popover-title\" style=\"text-align:center;background-color:#EFEFEF;\"></div>";
1207 $options .= " <div class=\"popover-content \" ></div>";
1208 $options .= "</div>'}}";
1209 $out .= "$('#".$keyprefix.$key.$keysuffix."').iconpicker(".$options.");";
1210 $out .= '</script>';
1211 }
1212 } elseif ($type == 'text') {
1213 if (!preg_match('/search_/', $keyprefix)) { // If keyprefix is search_ or search_options_, we must just use a simple text field
1214 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1215 $doleditor = new DolEditor($keyprefix.$key.$keysuffix, $value, '', 200, 'dolibarr_notes', 'In', false, false, false, ROWS_5, '90%');
1216 $out = (string) $doleditor->Create(1);
1217 } else {
1218 $out = '<input type="text" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam ? $moreparam : '').'>';
1219 }
1220 } elseif ($type == 'html') {
1221 if (!preg_match('/search_/', $keyprefix)) { // If keyprefix is search_ or search_options_, we must just use a simple text field
1222 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1223 $doleditor = new DolEditor($keyprefix.$key.$keysuffix, $value, '', 200, 'dolibarr_notes', 'In', false, false, isModEnabled('fckeditor') && getDolGlobalInt('FCKEDITOR_ENABLE_SOCIETE'), ROWS_5, '90%');
1224 $out = (string) $doleditor->Create(1);
1225 } else {
1226 $out = '<input type="text" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam ? $moreparam : '').'>';
1227 }
1228 } elseif ($type == 'boolean') {
1229 if (empty($mode)) {
1230 $checked = '';
1231 if (!empty($value)) {
1232 $checked = ' checked value="1" ';
1233 } else {
1234 $checked = ' value="1" ';
1235 }
1236 $out = '<input type="checkbox" class="flat valignmiddle'.($morecss ? ' '.$morecss : '').' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.$checked.' '.($moreparam ? $moreparam : '').'>';
1237 } else {
1238 $out = $form->selectyesno($keyprefix.$key.$keysuffix, $value, 1, false, 1);
1239 }
1240 $out .= '<input type="hidden" name="'.$keyprefix.$key.$keysuffix.'_boolean" value="1">'; // A hidden field ending with "_boolean" that is always set to 1.
1241 } elseif ($type == 'price') {
1242 if (!empty($value)) { // $value in memory is a php numeric, we format it into user number format.
1243 $value = price($value);
1244 }
1245 $out = '<input type="text" class="flat '.$morecss.' maxwidthonsmartphone right" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam ? $moreparam : '').' placeholder="'.$langs->getCurrencySymbol($conf->currency).'">';
1246 } elseif ($type == 'pricecy') {
1247 $currency = $conf->currency;
1248 if (!empty($value)) {
1249 // $value in memory is a php string like '10.01:USD'
1250 $pricetmp = explode(':', $value);
1251 $currency = !empty($pricetmp[1]) ? $pricetmp[1] : $conf->currency;
1252 $value = price($pricetmp[0]);
1253 }
1254 $out = '<input type="text" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam ? $moreparam : '').'> ';
1255 $out .= $form->selectCurrency($currency, $keyprefix.$key.$keysuffix.'currency_id');
1256 } elseif ($type == 'double') {
1257 if (!empty($value)) { // $value in memory is a php numeric, we format it into user number format.
1258 $value = price($value);
1259 }
1260 $out = '<input type="text" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam ? $moreparam : '').'> ';
1261 } elseif ($type == 'select') {
1262 $out = '';
1263 if ($mode) {
1264 $options = array();
1265 foreach ($param['options'] as $okey => $val) {
1266 if ((string) $okey == '') {
1267 continue;
1268 }
1269
1270 $valarray = explode('|', $val);
1271 $val = $valarray[0];
1272
1273 if ($langfile && $val) {
1274 $options[$okey] = $langs->trans($val);
1275 } else {
1276 $options[$okey] = $val;
1277 }
1278 }
1279 $selected = array();
1280 if (!is_array($value)) {
1281 $selected = explode(',', $value);
1282 }
1283
1284 $out .= $form->multiselectarray($keyprefix.$key.$keysuffix, $options, $selected, 0, 0, $morecss, 0, 0, '', '', '', !empty($conf->use_javascript_ajax) && !getDolGlobalString('MAIN_EXTRAFIELDS_DISABLE_SELECT2'));
1285 } else {
1286 if (!empty($conf->use_javascript_ajax) && !getDolGlobalString('MAIN_EXTRAFIELDS_DISABLE_SELECT2')) {
1287 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
1288 $out .= ajax_combobox($keyprefix.$key.$keysuffix, array(), 0);
1289 }
1290
1291 $out .= '<select class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam ? $moreparam : '').'>';
1292 $out .= '<option value="0">&nbsp;</option>';
1293 foreach ($param['options'] as $key2 => $val2) {
1294 if ((string) $key2 == '') {
1295 continue;
1296 }
1297 $valarray = explode('|', $val2);
1298 $val2 = $valarray[0];
1299 $parent = '';
1300 if (!empty($valarray[1])) {
1301 $parent = $valarray[1];
1302 }
1303 $out .= '<option value="'.$key2.'"';
1304 $out .= (((string) $value == (string) $key2) ? ' selected' : '');
1305 $out .= (!empty($parent) ? ' parent="'.$parent.'"' : '');
1306 $out .= '>';
1307 if ($langfile && $val2) {
1308 $out .= $langs->trans($val2);
1309 } else {
1310 $out .= $val2;
1311 }
1312 $out .= '</option>';
1313 }
1314 $out .= '</select>';
1315 }
1316 } elseif ($type == 'sellist') {
1317 $out = '';
1318 if (!empty($conf->use_javascript_ajax) && !getDolGlobalString('MAIN_EXTRAFIELDS_DISABLE_SELECT2')) {
1319 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
1320 $out .= ajax_combobox($keyprefix.$key.$keysuffix, array(), 0);
1321 }
1322
1323 $out .= '<select class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam ? $moreparam : '').'>';
1324 if (is_array($param['options'])) {
1325 $param_list = array_keys($param['options']);
1326 $InfoFieldList = explode(":", $param_list[0]);
1327 $parentName = '';
1328 $parentField = '';
1329 // 0 : tableName
1330 // 1 : label field name
1331 // 2 : key fields name (if differ of rowid)
1332 // 3 : key field parent (for dependent lists)
1333 // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
1334 // 5 : id category type
1335 // 6 : ids categories list separated by comma for category root
1336 // 7 : sort by (to be close to common object)
1337 $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2].' as rowid');
1338
1339
1340 if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) {
1341 if (strpos($InfoFieldList[4], 'extra.') !== false) {
1342 $keyList = 'main.'.$InfoFieldList[2].' as rowid';
1343 } else {
1344 $keyList = $InfoFieldList[2].' as rowid';
1345 }
1346 }
1347 if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) {
1348 list($parentName, $parentField) = explode('|', $InfoFieldList[3]);
1349 $keyList .= ', '.$parentField;
1350 }
1351
1352 $filter_categorie = false;
1353 if (count($InfoFieldList) > 5) {
1354 if ($InfoFieldList[0] == 'categorie') {
1355 $filter_categorie = true;
1356 }
1357 }
1358
1359 if ($filter_categorie === false) {
1360 $fields_label = explode('|', $InfoFieldList[1]);
1361 if (is_array($fields_label)) {
1362 $keyList .= ', ';
1363 $keyList .= implode(', ', $fields_label);
1364 }
1365
1366 $sqlwhere = '';
1367 $sql = "SELECT ".$keyList;
1368 $sql .= ' FROM '.$this->db->prefix().$InfoFieldList[0];
1369 if (!empty($InfoFieldList[4])) {
1370 // can use current entity filter
1371 if (strpos($InfoFieldList[4], '$ENTITY$') !== false) {
1372 $InfoFieldList[4] = str_replace('$ENTITY$', (string) $conf->entity, $InfoFieldList[4]);
1373 }
1374 // can use SELECT request
1375 if (strpos($InfoFieldList[4], '$SEL$') !== false) {
1376 $InfoFieldList[4] = str_replace('$SEL$', 'SELECT', $InfoFieldList[4]);
1377 }
1378
1379 // current object id can be use into filter
1380 if (strpos($InfoFieldList[4], '$ID$') !== false && !empty($objectid)) {
1381 $InfoFieldList[4] = str_replace('$ID$', (string) $objectid, $InfoFieldList[4]);
1382 } else {
1383 $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]);
1384 }
1385 //We have to join on extrafield table
1386 if (strpos($InfoFieldList[4], 'extra.') !== false) {
1387 $sql .= ' as main, '.$this->db->prefix().$InfoFieldList[0].'_extrafields as extra';
1388 $sqlwhere .= " WHERE extra.fk_object=main.".$InfoFieldList[2]." AND ".$InfoFieldList[4];
1389 } else {
1390 $sqlwhere .= " WHERE ".$InfoFieldList[4];
1391 }
1392 } else {
1393 $sqlwhere .= ' WHERE 1=1';
1394 }
1395 // Some tables may have field, some other not. For the moment we disable it.
1396 if (in_array($InfoFieldList[0], array('tablewithentity'))) {
1397 $sqlwhere .= ' AND entity = '.((int) $conf->entity);
1398 }
1399 $sql .= $sqlwhere;
1400 //print $sql;
1401
1402 $sql .= ' ORDER BY '.implode(', ', $fields_label);
1403
1404 dol_syslog(get_class($this).'::showInputField type=sellist', LOG_DEBUG);
1405 $resql = $this->db->query($sql);
1406 if ($resql) {
1407 $out .= '<option value="0">&nbsp;</option>';
1408 $num = $this->db->num_rows($resql);
1409 $i = 0;
1410 while ($i < $num) {
1411 $labeltoshow = '';
1412 $obj = $this->db->fetch_object($resql);
1413
1414 // Several field into label (eq table:code|label:rowid)
1415 $notrans = false;
1416 $fields_label = explode('|', $InfoFieldList[1]);
1417 if (is_array($fields_label) && count($fields_label) > 1) {
1418 $notrans = true;
1419 foreach ($fields_label as $field_toshow) {
1420 $labeltoshow .= $obj->$field_toshow.' ';
1421 }
1422 } else {
1423 $labeltoshow = $obj->{$InfoFieldList[1]};
1424 }
1425
1426 if ($value == $obj->rowid) {
1427 if (!$notrans) {
1428 foreach ($fields_label as $field_toshow) {
1429 $translabel = $langs->trans($obj->$field_toshow);
1430 $labeltoshow = $translabel.' ';
1431 }
1432 }
1433 $out .= '<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
1434 } else {
1435 if (!$notrans) {
1436 $translabel = $langs->trans($obj->{$InfoFieldList[1]});
1437 $labeltoshow = $translabel;
1438 }
1439 if (empty($labeltoshow)) {
1440 $labeltoshow = '(not defined)';
1441 }
1442
1443 if (!empty($InfoFieldList[3]) && $parentField) {
1444 $parent = $parentName.':'.$obj->{$parentField};
1445 }
1446
1447 $out .= '<option value="'.$obj->rowid.'"';
1448 $out .= ($value == $obj->rowid ? ' selected' : '');
1449 $out .= (!empty($parent) ? ' parent="'.$parent.'"' : '');
1450 $out .= '>'.$labeltoshow.'</option>';
1451 }
1452
1453 $i++;
1454 }
1455 $this->db->free($resql);
1456 } else {
1457 print 'Error in request '.$sql.' '.$this->db->lasterror().'. Check setup of extra parameters.<br>';
1458 }
1459 } else {
1460 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1461 $data = $form->select_all_categories(Categorie::$MAP_ID_TO_CODE[$InfoFieldList[5]], '', 'parent', 64, $InfoFieldList[6], 1, 1);
1462 $out .= '<option value="0">&nbsp;</option>';
1463 if (is_array($data)) {
1464 foreach ($data as $data_key => $data_value) {
1465 $out .= '<option value="'.$data_key.'"';
1466 $out .= ($value == $data_key ? ' selected' : '');
1467 $out .= '>'.$data_value.'</option>';
1468 }
1469 }
1470 }
1471 }
1472 $out .= '</select>';
1473 } elseif ($type == 'checkbox') {
1474 $value_arr = $value;
1475 if (!is_array($value)) {
1476 $value_arr = explode(',', $value);
1477 }
1478 $out = $form->multiselectarray($keyprefix.$key.$keysuffix, (empty($param['options']) ? null : $param['options']), $value_arr, '', 0, '', 0, '100%');
1479 } elseif ($type == 'radio') {
1480 $out = '';
1481 foreach ($param['options'] as $keyopt => $val) {
1482 $out .= '<input class="flat '.$morecss.'" type="radio" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam ? $moreparam : '');
1483 $out .= ' value="'.$keyopt.'"';
1484 $out .= ' id="'.$keyprefix.$key.$keysuffix.'_'.$keyopt.'"';
1485 $out .= ($value == $keyopt ? 'checked' : '');
1486 $out .= '/><label for="'.$keyprefix.$key.$keysuffix.'_'.$keyopt.'">'.$langs->trans($val).'</label><br>';
1487 }
1488 } elseif ($type == 'chkbxlst') {
1489 if (is_array($value)) {
1490 $value_arr = $value;
1491 } else {
1492 $value_arr = explode(',', $value);
1493 }
1494
1495 if (is_array($param['options'])) {
1496 $param_list = array_keys($param['options']);
1497 $InfoFieldList = explode(":", $param_list[0]);
1498 $parentName = '';
1499 $parentField = '';
1500 // 0 : tableName
1501 // 1 : label field name
1502 // 2 : key fields name (if differ of rowid)
1503 // 3 : key field parent (for dependent lists)
1504 // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
1505 // 5 : id category type
1506 // 6 : ids categories list separated by comma for category root
1507 // 7 : sort by (to be close to common object)
1508 $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2].' as rowid');
1509
1510 if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) {
1511 list($parentName, $parentField) = explode('|', $InfoFieldList[3]);
1512 $keyList .= ', '.$parentField;
1513 }
1514 if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) {
1515 if (strpos($InfoFieldList[4], 'extra.') !== false) {
1516 $keyList = 'main.'.$InfoFieldList[2].' as rowid';
1517 } else {
1518 $keyList = $InfoFieldList[2].' as rowid';
1519 }
1520 }
1521
1522 $filter_categorie = false;
1523 if (count($InfoFieldList) > 5) {
1524 if ($InfoFieldList[0] == 'categorie') {
1525 $filter_categorie = true;
1526 }
1527 }
1528
1529 if ($filter_categorie === false) {
1530 $fields_label = explode('|', $InfoFieldList[1]);
1531 if (is_array($fields_label)) {
1532 $keyList .= ', ';
1533 $keyList .= implode(', ', $fields_label);
1534 }
1535
1536 $sqlwhere = '';
1537 $sql = "SELECT ".$keyList;
1538 $sql .= ' FROM '.$this->db->prefix().$InfoFieldList[0];
1539 if (!empty($InfoFieldList[4])) {
1540 // can use current entity filter
1541 if (strpos($InfoFieldList[4], '$ENTITY$') !== false) {
1542 $InfoFieldList[4] = str_replace('$ENTITY$', (string) $conf->entity, $InfoFieldList[4]);
1543 }
1544 // can use SELECT request
1545 if (strpos($InfoFieldList[4], '$SEL$') !== false) {
1546 $InfoFieldList[4] = str_replace('$SEL$', 'SELECT', $InfoFieldList[4]);
1547 }
1548
1549 // current object id can be use into filter
1550 if (strpos($InfoFieldList[4], '$ID$') !== false && !empty($objectid)) {
1551 $InfoFieldList[4] = str_replace('$ID$', (string) $objectid, $InfoFieldList[4]);
1552 } elseif (preg_match("#^.*list.php$#", $_SERVER["PHP_SELF"])) {
1553 // Pattern for word=$ID$
1554 $word = '\b[a-zA-Z0-9-\.-_]+\b=\$ID\$';
1555
1556 // Removing spaces around =, ( and )
1557 $InfoFieldList[4] = preg_replace('# *(=|\‍(|\‍)) *#', '$1', $InfoFieldList[4]);
1558
1559 $nbPreg = 1;
1560 // While we have parenthesis
1561 while ($nbPreg != 0) {
1562 // Initialise counters
1563 $nbPregRepl = $nbPregSel = 0;
1564 // Remove all parenthesis not preceded with '=' sign
1565 $InfoFieldList[4] = preg_replace('#([^=])(\‍([^)^(]*('.$word.')[^)^(]*\‍))#', '$1 $3 ', $InfoFieldList[4], -1, $nbPregRepl);
1566 // Remove all escape characters around '=' and parenthesis
1567 $InfoFieldList[4] = preg_replace('# *(=|\‍(|\‍)) *#', '$1', $InfoFieldList[4]);
1568 // Remove all parentheses preceded with '='
1569 $InfoFieldList[4] = preg_replace('#\b[a-zA-Z0-9-\.-_]+\b=\‍([^)^(]*('.$word.')[^)^(]*\‍)#', '$1 ', $InfoFieldList[4], -1, $nbPregSel);
1570 // On retire les escapes autour des = et parenthèses
1571 $InfoFieldList[4] = preg_replace('# *(=|\‍(|\‍)) *#', '$1', $InfoFieldList[4]);
1572
1573 // UPdate the totals counter for the loop
1574 $nbPreg = $nbPregRepl + $nbPregSel;
1575 }
1576
1577 // In case there is AND ou OR, before or after
1578 $matchCondition = array();
1579 preg_match('#(AND|OR|) *('.$word.') *(AND|OR|)#', $InfoFieldList[4], $matchCondition);
1580 while (!empty($matchCondition[0])) {
1581 // If the two sides differ but are not empty
1582 if (!empty($matchCondition[1]) && !empty($matchCondition[3]) && $matchCondition[1] != $matchCondition[3]) {
1583 // Nobody sain would do that without parentheses
1584 $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]);
1585 } else {
1586 if (!empty($matchCondition[1])) {
1587 $boolCond = (($matchCondition[1] == "AND") ? ' AND TRUE ' : ' OR FALSE ');
1588 $InfoFieldList[4] = str_replace($matchCondition[0], $boolCond.$matchCondition[3], $InfoFieldList[4]);
1589 } elseif (!empty($matchCondition[3])) {
1590 $boolCond = (($matchCondition[3] == "AND") ? ' TRUE AND ' : ' FALSE OR');
1591 $InfoFieldList[4] = str_replace($matchCondition[0], $boolCond, $InfoFieldList[4]);
1592 } else {
1593 $InfoFieldList[4] = " TRUE ";
1594 }
1595 }
1596
1597 // In case there is AND ou OR, before or after
1598 preg_match('#(AND|OR|) *('.$word.') *(AND|OR|)#', $InfoFieldList[4], $matchCondition);
1599 }
1600 } else {
1601 $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]);
1602 }
1603
1604 // We have to join on extrafield table
1605 if (strpos($InfoFieldList[4], 'extra.') !== false) {
1606 $sql .= ' as main, '.$this->db->prefix().$InfoFieldList[0].'_extrafields as extra';
1607 $sqlwhere .= " WHERE extra.fk_object=main.".$InfoFieldList[2]." AND ".$InfoFieldList[4];
1608 } else {
1609 $sqlwhere .= " WHERE ".$InfoFieldList[4];
1610 }
1611 } else {
1612 $sqlwhere .= ' WHERE 1=1';
1613 }
1614 // Some tables may have field, some other not. For the moment we disable it.
1615 if (in_array($InfoFieldList[0], array('tablewithentity'))) {
1616 $sqlwhere .= " AND entity = ".((int) $conf->entity);
1617 }
1618 // $sql.=preg_replace('/^ AND /','',$sqlwhere);
1619 // print $sql;
1620
1621 $sql .= $sqlwhere;
1622 $sql .= ' ORDER BY '.implode(', ', $fields_label);
1623
1624 dol_syslog(get_class($this).'::showInputField type=chkbxlst', LOG_DEBUG);
1625 $resql = $this->db->query($sql);
1626 if ($resql) {
1627 $num = $this->db->num_rows($resql);
1628 $i = 0;
1629
1630 $data = array();
1631
1632 while ($i < $num) {
1633 $labeltoshow = '';
1634 $obj = $this->db->fetch_object($resql);
1635
1636 $notrans = false;
1637 // Several field into label (eq table:code|label:rowid)
1638 $fields_label = explode('|', $InfoFieldList[1]);
1639 if (is_array($fields_label)) {
1640 $notrans = true;
1641 foreach ($fields_label as $field_toshow) {
1642 $labeltoshow .= $obj->$field_toshow.' ';
1643 }
1644 } else {
1645 $labeltoshow = $obj->{$InfoFieldList[1]};
1646 }
1647 $labeltoshow = dol_trunc($labeltoshow, 45);
1648
1649 if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1650 $labeltoshow = '';
1651 foreach ($fields_label as $field_toshow) {
1652 $translabel = $langs->trans($obj->$field_toshow);
1653 if ($translabel != $obj->$field_toshow) {
1654 $labeltoshow .= ' '.dol_trunc($translabel, 18).' ';
1655 } else {
1656 $labeltoshow .= ' '.dol_trunc($obj->$field_toshow, 18).' ';
1657 }
1658 }
1659 $data[$obj->rowid] = $labeltoshow;
1660 } else {
1661 if (!$notrans) {
1662 $translabel = $langs->trans($obj->{$InfoFieldList[1]});
1663 if ($translabel != $obj->{$InfoFieldList[1]}) {
1664 $labeltoshow = dol_trunc($translabel, 18);
1665 } else {
1666 $labeltoshow = dol_trunc($obj->{$InfoFieldList[1]}, 18);
1667 }
1668 }
1669 if (empty($labeltoshow)) {
1670 $labeltoshow = '(not defined)';
1671 }
1672
1673 if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1674 $data[$obj->rowid] = $labeltoshow;
1675 }
1676
1677 if (!empty($InfoFieldList[3]) && $parentField) {
1678 $parent = $parentName.':'.$obj->{$parentField};
1679 }
1680
1681 $data[$obj->rowid] = $labeltoshow;
1682 }
1683
1684 $i++;
1685 }
1686 $this->db->free($resql);
1687
1688 $out = $form->multiselectarray($keyprefix.$key.$keysuffix, $data, $value_arr, '', 0, '', 0, '100%');
1689 } else {
1690 print 'Error in request '.$sql.' '.$this->db->lasterror().'. Check setup of extra parameters.<br>';
1691 }
1692 } else {
1693 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1694 $data = $form->select_all_categories(Categorie::$MAP_ID_TO_CODE[$InfoFieldList[5]], '', 'parent', 64, $InfoFieldList[6], 1, 1);
1695 $out = $form->multiselectarray($keyprefix.$key.$keysuffix, $data, $value_arr, '', 0, '', 0, '100%');
1696 }
1697 }
1698 } elseif ($type == 'link') {
1699 $param_list = array_keys($param['options']); // $param_list[0] = 'ObjectName:classPath' but can also be 'ObjectName:classPath:1:(status:=:1)'
1700 /* Removed.
1701 The selectForForms is called with parameter $objectfield defined, so the app can retrieve the filter inside the ajax component instead of being provided as parameters. The
1702 filter was used to pass SQL requests leading to serious SQL injection problem. This should not be possible. Also the call of the ajax was broken by some WAF.
1703 if (strpos($param_list[0], '$ID$') !== false && !empty($objectid)) {
1704 $param_list[0] = str_replace('$ID$', $objectid, $param_list[0]);
1705 }*/
1706 $showempty = (($required && $default != '') ? 0 : 1);
1707
1708 $tmparray = explode(':', $param_list[0]);
1709
1710 $element = $extrafieldsobjectkey; // $extrafieldsobjectkey comes from $object->table_element but we need $object->element
1711 if ($element == 'socpeople') {
1712 $element = 'contact';
1713 } elseif ($element == 'projet') {
1714 $element = 'project';
1715 }
1716
1717 //$objectdesc = $param_list[0]; // Example: 'ObjectName:classPath:1:(status:=:1)' Replaced by next line: this was propagated also a filter by ajax call that was blocked by some WAF
1718 $objectdesc = $tmparray[0]; // Example: 'ObjectName:classPath' To not propagate any filter (selectForForms do ajax call and propagating SQL filter is blocked by some WAF). Also we should use the one into the definition in the ->fields of $elem if found.
1719 $objectfield = $element.':options_'.$key; // Example: 'actioncomm:options_fff' To be used in priority to know object linked with all its definition (including filters)
1720
1721 $out = $form->selectForForms($objectdesc, $keyprefix.$key.$keysuffix, $value, $showempty, '', '', $morecss, '', 0, 0, '', $objectfield);
1722 } elseif (in_array($type, ['point', 'multipts', 'linestrg', 'polygon'])) {
1723 require_once DOL_DOCUMENT_ROOT.'/core/class/dolgeophp.class.php';
1724 $dolgeophp = new DolGeoPHP($this->db);
1725 $geojson = '{}';
1726 $centroidjson = getDolGlobalString('MAIN_INFO_SOCIETE_GEO_COORDINATES', '{}');
1727 if (!empty($value)) {
1728 $tmparray = $dolgeophp->parseGeoString($value);
1729 $geojson = $tmparray['geojson'];
1730 $centroidjson = $tmparray['centroidjson'];
1731 }
1732 if (!preg_match('/search_/', $keyprefix)) {
1733 require_once DOL_DOCUMENT_ROOT.'/core/class/geomapeditor.class.php';
1734 $geomapeditor = new GeoMapEditor();
1735 $out .= $geomapeditor->getHtml($keyprefix.$key.$keysuffix, $geojson, $centroidjson, $type);
1736 } else {
1737 // If keyprefix is search_ or search_options_, we must just use a simple text field
1738 $out = '';
1739 }
1740 } elseif ($type == 'password') {
1741 // If prefix is 'search_', field is used as a filter, we use a common text field.
1742 $out = '<input style="display:none" type="text" name="fakeusernameremembered">'; // Hidden field to reduce impact of evil Google Chrome autopopulate bug.
1743 $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 : '').'>';
1744 }
1745 if (!empty($hidden)) {
1746 $out = '<input type="hidden" value="'.$value.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'"/>';
1747 }
1748 /* Add comments
1749 if ($type == 'date') $out.=' (YYYY-MM-DD)';
1750 elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)';
1751 */
1752 /*if (!empty($help) && $keyprefix != 'search_options_') {
1753 $out .= $form->textwithpicto('', $help, 1, 'help', '', 0, 3);
1754 }*/
1755 return $out;
1756 }
1757
1758
1769 public function showOutputField($key, $value, $moreparam = '', $extrafieldsobjectkey = '', $outputlangs = null)
1770 {
1771 global $conf, $langs;
1772
1773 if (is_null($outputlangs) || !is_object($outputlangs)) {
1774 $outputlangs = $langs;
1775 }
1776
1777 if (empty($extrafieldsobjectkey)) {
1778 dol_syslog(get_class($this).'::showOutputField extrafieldsobjectkey required', LOG_ERR);
1779 return 'BadValueForParamExtraFieldsObjectKey';
1780 }
1781
1782 $label = $this->attributes[$extrafieldsobjectkey]['label'][$key];
1783 $type = $this->attributes[$extrafieldsobjectkey]['type'][$key];
1784 $size = $this->attributes[$extrafieldsobjectkey]['size'][$key]; // Can be '255', '24,8'...
1785 $default = $this->attributes[$extrafieldsobjectkey]['default'][$key];
1786 $computed = $this->attributes[$extrafieldsobjectkey]['computed'][$key];
1787 $unique = $this->attributes[$extrafieldsobjectkey]['unique'][$key];
1788 $required = $this->attributes[$extrafieldsobjectkey]['required'][$key];
1789 $param = $this->attributes[$extrafieldsobjectkey]['param'][$key];
1790 $perms = (int) dol_eval($this->attributes[$extrafieldsobjectkey]['perms'][$key], 1, 1, '2');
1791 $langfile = $this->attributes[$extrafieldsobjectkey]['langfile'][$key];
1792 $list = (string) dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1, 1, '2');
1793 $help = $this->attributes[$extrafieldsobjectkey]['help'][$key];
1794 $cssview = $this->attributes[$extrafieldsobjectkey]['cssview'][$key];
1795
1796 $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)
1797
1798 if ($hidden) {
1799 return ''; // This is a protection. If field is hidden, we should just not call this method.
1800 }
1801
1802 //if ($computed) $value = // $value is already calculated into $value before calling this method
1803
1804 $showsize = 0;
1805 if ($type == 'date') {
1806 $showsize = 10;
1807 if ($value !== '') {
1808 $value = dol_print_date($value, 'day'); // For date without hour, date is always GMT for storage and output
1809 }
1810 } elseif ($type == 'datetime') {
1811 $showsize = 19;
1812 if ($value !== '') {
1813 $value = dol_print_date($value, 'dayhour', 'tzuserrel');
1814 }
1815 } elseif ($type == 'datetimegmt') {
1816 $showsize = 19;
1817 if ($value !== '') {
1818 $value = dol_print_date($value, 'dayhour', 'gmt');
1819 }
1820 } elseif ($type == 'int') {
1821 $showsize = 10;
1822 } elseif ($type == 'double') {
1823 if (!empty($value)) {
1824 //$value=price($value);
1825 $sizeparts = explode(",", $size);
1826 $number_decimals = array_key_exists(1, $sizeparts) ? $sizeparts[1] : 0;
1827 $value = price($value, 0, $outputlangs, 0, 0, $number_decimals, '');
1828 }
1829 } elseif ($type == 'boolean') {
1830 $checked = '';
1831 if (!empty($value)) {
1832 $checked = ' checked ';
1833 }
1834 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER') < 2) {
1835 $value = '<input type="checkbox" '.$checked.' '.($moreparam ? $moreparam : '').' readonly disabled>';
1836 } else {
1837 $value = yn($value ? 1 : 0);
1838 }
1839 } elseif ($type == 'mail') {
1840 $value = dol_print_email($value, 0, 0, 0, 64, 1, 1);
1841 } elseif ($type == 'ip') {
1842 $value = dol_print_ip($value, 0);
1843 } elseif ($type == 'icon') {
1844 $value = '<span class="'.$value.'"></span>';
1845 } elseif ($type == 'url') {
1846 $value = dol_print_url($value, '_blank', 32, 1);
1847 } elseif ($type == 'phone') {
1848 $value = dol_print_phone($value, '', 0, 0, '', '&nbsp;', 'phone');
1849 } elseif ($type == 'price') {
1850 //$value = price($value, 0, $langs, 0, 0, -1, $conf->currency);
1851 if ($value || $value == '0') {
1852 $value = price($value, 0, $outputlangs, 0, $conf->global->MAIN_MAX_DECIMALS_TOT, -1).' '.$outputlangs->getCurrencySymbol($conf->currency);
1853 }
1854 } elseif ($type == 'pricecy') {
1855 $currency = $conf->currency;
1856 if (!empty($value)) {
1857 // $value in memory is a php string like '0.01:EUR'
1858 $pricetmp = explode(':', $value);
1859 $currency = !empty($pricetmp[1]) ? $pricetmp[1] : $conf->currency;
1860 $value = $pricetmp[0];
1861 }
1862 if ($value || $value == '0') {
1863 $value = price($value, 0, $outputlangs, 0, $conf->global->MAIN_MAX_DECIMALS_TOT, -1, $currency);
1864 }
1865 } elseif ($type == 'select') {
1866 $valstr = (!empty($param['options'][$value]) ? $param['options'][$value] : '');
1867 if (($pos = strpos($valstr, "|")) !== false) {
1868 $valstr = substr($valstr, 0, $pos);
1869 }
1870 if ($langfile && $valstr) {
1871 $value = $outputlangs->trans($valstr);
1872 } else {
1873 $value = $valstr;
1874 }
1875 } elseif ($type == 'sellist') {
1876 $param_list = array_keys($param['options']);
1877 $InfoFieldList = explode(":", $param_list[0]);
1878
1879 $selectkey = "rowid";
1880 $keyList = 'rowid';
1881
1882 if (count($InfoFieldList) >= 3) {
1883 $selectkey = $InfoFieldList[2];
1884 $keyList = $InfoFieldList[2].' as rowid';
1885 }
1886
1887 $fields_label = explode('|', $InfoFieldList[1]);
1888 if (is_array($fields_label)) {
1889 $keyList .= ', ';
1890 $keyList .= implode(', ', $fields_label);
1891 }
1892
1893 $filter_categorie = false;
1894 if (count($InfoFieldList) > 5) {
1895 if ($InfoFieldList[0] == 'categorie') {
1896 $filter_categorie = true;
1897 }
1898 }
1899
1900 $sql = "SELECT ".$keyList;
1901 $sql .= ' FROM '.$this->db->prefix().$InfoFieldList[0];
1902 if (!empty($InfoFieldList[4]) && strpos($InfoFieldList[4], 'extra.') !== false) {
1903 $sql .= ' as main';
1904 }
1905 if ($selectkey == 'rowid' && empty($value)) {
1906 $sql .= " WHERE ".$selectkey." = 0";
1907 } elseif ($selectkey == 'rowid') {
1908 $sql .= " WHERE ".$selectkey." = ".((int) $value);
1909 } else {
1910 $sql .= " WHERE ".$selectkey." = '".$this->db->escape($value)."'";
1911 }
1912
1913 //$sql.= ' AND entity = '.$conf->entity;
1914
1915 dol_syslog(get_class($this).':showOutputField:$type=sellist', LOG_DEBUG);
1916 $resql = $this->db->query($sql);
1917 if ($resql) {
1918 if ($filter_categorie === false) {
1919 $value = ''; // value was used, so now we reste it to use it to build final output
1920
1921 $obj = $this->db->fetch_object($resql);
1922
1923 // Several field into label (eq table:code|label:rowid)
1924 $fields_label = explode('|', $InfoFieldList[1]);
1925
1926 if (is_array($fields_label) && count($fields_label) > 1) {
1927 foreach ($fields_label as $field_toshow) {
1928 $translabel = '';
1929 if (!empty($obj->$field_toshow)) {
1930 $translabel = $outputlangs->trans($obj->$field_toshow);
1931
1932 if ($translabel != $obj->$field_toshow) {
1933 $value .= dol_trunc($translabel, 24) . ' ';
1934 } else {
1935 $value .= $obj->$field_toshow . ' ';
1936 }
1937 }
1938 }
1939 } else {
1940 $translabel = '';
1941 $tmppropname = $InfoFieldList[1];
1942 //$obj->$tmppropname = '';
1943 if (!empty(isset($obj->$tmppropname) ? $obj->$tmppropname : '')) {
1944 $translabel = $outputlangs->trans($obj->$tmppropname);
1945 }
1946 if ($translabel != (isset($obj->$tmppropname) ? $obj->$tmppropname : '')) {
1947 $value = dol_trunc($translabel, 18);
1948 } else {
1949 $value = isset($obj->$tmppropname) ? $obj->$tmppropname : '';
1950 }
1951 }
1952 } else {
1953 $toprint = array();
1954 $obj = $this->db->fetch_object($resql);
1955 if ($obj->rowid) {
1956 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1957 $c = new Categorie($this->db);
1958 $result = $c->fetch($obj->rowid);
1959 if ($result > 0) {
1960 $ways = $c->print_all_ways(); // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formatted text
1961 foreach ($ways as $way) {
1962 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories"' . ($c->color ? ' style="background: #' . $c->color . ';"' : ' style="background: #bbb"') . '>' . img_object('', 'category') . ' ' . $way . '</li>';
1963 }
1964 }
1965 }
1966 $value = '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
1967 }
1968 } else {
1969 dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING);
1970 }
1971 } elseif ($type == 'radio') {
1972 if (!isset($param['options'][$value])) {
1973 $outputlangs->load('errors');
1974 $value = $outputlangs->trans('ErrorNoValueForRadioType');
1975 } else {
1976 $value = $outputlangs->trans($param['options'][$value]);
1977 }
1978 } elseif ($type == 'checkbox') {
1979 $value_arr = explode(',', $value);
1980 $value = '';
1981 $toprint = array();
1982 if (is_array($value_arr)) {
1983 foreach ($value_arr as $keyval => $valueval) {
1984 if (!empty($valueval)) {
1985 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #bbb">'.$param['options'][$valueval].'</li>';
1986 }
1987 }
1988 }
1989 $value = '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
1990 } elseif ($type == 'chkbxlst') {
1991 $value_arr = explode(',', $value);
1992
1993 $param_list = array_keys($param['options']);
1994 $InfoFieldList = explode(":", $param_list[0]);
1995
1996 $selectkey = "rowid";
1997 $keyList = 'rowid';
1998
1999 if (count($InfoFieldList) >= 3) {
2000 $selectkey = $InfoFieldList[2];
2001 $keyList = $InfoFieldList[2].' as rowid';
2002 }
2003
2004 $fields_label = explode('|', $InfoFieldList[1]);
2005 if (is_array($fields_label)) {
2006 $keyList .= ', ';
2007 $keyList .= implode(', ', $fields_label);
2008 }
2009
2010 $filter_categorie = false;
2011 if (count($InfoFieldList) > 5) {
2012 if ($InfoFieldList[0] == 'categorie') {
2013 $filter_categorie = true;
2014 }
2015 }
2016
2017 $sql = "SELECT ".$keyList;
2018 $sql .= " FROM ".$this->db->prefix().$InfoFieldList[0];
2019 if (strpos($InfoFieldList[4], 'extra.') !== false) {
2020 $sql .= ' as main';
2021 }
2022 // $sql.= " WHERE ".$selectkey."='".$this->db->escape($value)."'";
2023 // $sql.= ' AND entity = '.$conf->entity;
2024
2025 dol_syslog(get_class($this).':showOutputField:$type=chkbxlst', LOG_DEBUG);
2026 $resql = $this->db->query($sql);
2027 if ($resql) {
2028 if ($filter_categorie === false) {
2029 $value = ''; // value was used, so now we reste it to use it to build final output
2030 $toprint = array();
2031 while ($obj = $this->db->fetch_object($resql)) {
2032 // Several field into label (eq table:code|label:rowid)
2033 $fields_label = explode('|', $InfoFieldList[1]);
2034 if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
2035 if (is_array($fields_label) && count($fields_label) > 1) {
2036 $label = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #bbb">';
2037 foreach ($fields_label as $field_toshow) {
2038 $translabel = '';
2039 if (!empty($obj->$field_toshow)) {
2040 $translabel = $outputlangs->trans($obj->$field_toshow);
2041 }
2042 if ($translabel != $field_toshow) {
2043 $label .= ' '.dol_trunc($translabel, 18);
2044 } else {
2045 $label .= ' '.$obj->$field_toshow;
2046 }
2047 }
2048 $label .= '</li>';
2049 $toprint[] = $label;
2050 } else {
2051 $translabel = '';
2052 if (!empty($obj->{$InfoFieldList[1]})) {
2053 $translabel = $outputlangs->trans($obj->{$InfoFieldList[1]});
2054 }
2055 if ($translabel != $obj->{$InfoFieldList[1]}) {
2056 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #bbb">'.dol_trunc($translabel, 18).'</li>';
2057 } else {
2058 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #bbb">'.$obj->{$InfoFieldList[1]}.'</li>';
2059 }
2060 }
2061 }
2062 }
2063 } else {
2064 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
2065
2066 $toprint = array();
2067 while ($obj = $this->db->fetch_object($resql)) {
2068 if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
2069 $c = new Categorie($this->db);
2070 $c->fetch($obj->rowid);
2071 $ways = $c->print_all_ways(); // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formatted text
2072 foreach ($ways as $way) {
2073 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories"'.($c->color ? ' style="background: #'.$c->color.';"' : ' style="background: #bbb"').'>'.img_object('', 'category').' '.$way.'</li>';
2074 }
2075 }
2076 }
2077 }
2078 if (!empty($toprint)) {
2079 $value = '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
2080 }
2081 } else {
2082 dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING);
2083 }
2084 } elseif ($type == 'link') {
2085 $out = '';
2086
2087 // Only if something to display (perf)
2088 if ($value) { // If we have -1 here, pb is into insert, not into output (fix insert instead of changing code here to compensate)
2089 $param_list = array_keys($param['options']); // $param_list='ObjectName:classPath'
2090
2091 $InfoFieldList = explode(":", $param_list[0]);
2092 $classname = $InfoFieldList[0];
2093 $classpath = $InfoFieldList[1];
2094 if (!empty($classpath)) {
2095 dol_include_once($InfoFieldList[1]);
2096 if ($classname && class_exists($classname)) {
2097 $object = new $classname($this->db);
2098 $object->fetch($value);
2099 $value = $object->getNomUrl(3);
2100 }
2101 } else {
2102 dol_syslog('Error bad setup of extrafield', LOG_WARNING);
2103 return 'Error bad setup of extrafield';
2104 }
2105 }
2106 } elseif ($type == 'point') {
2107 if (!empty($value)) {
2108 require_once DOL_DOCUMENT_ROOT.'/core/class/dolgeophp.class.php';
2109 $dolgeophp = new DolGeoPHP($this->db);
2110 $value = $dolgeophp->getXYString($value);
2111 } else {
2112 $value = '';
2113 }
2114 } elseif (in_array($type, ['multipts','linestrg', 'polygon'])) {
2115 if (!empty($value)) {
2116 require_once DOL_DOCUMENT_ROOT.'/core/class/dolgeophp.class.php';
2117 $dolgeophp = new DolGeoPHP($this->db);
2118 $value = $dolgeophp->getPointString($value);
2119 } else {
2120 $value = '';
2121 }
2122 } elseif ($type == 'text') {
2123 $value = '<div class="'.($cssview ? $cssview : 'shortmessagecut').'">'.dol_htmlentitiesbr($value).'</div>';
2124 } elseif ($type == 'html') {
2125 $value = dol_htmlentitiesbr($value);
2126 } elseif ($type == 'password') {
2127 $value = dol_trunc(preg_replace('/./i', '*', $value), 8, 'right', 'UTF-8', 1);
2128 } else {
2129 $showsize = round((float) $size);
2130 if ($showsize > 48) {
2131 $showsize = 48;
2132 }
2133 }
2134
2135 //print $type.'-'.$size;
2136 $out = $value;
2137
2138 return $out;
2139 }
2140
2148 public function getAlignFlag($key, $extrafieldsobjectkey = '')
2149 {
2150 $type = 'varchar';
2151 if (!empty($extrafieldsobjectkey)) {
2152 $type = $this->attributes[$extrafieldsobjectkey]['type'][$key];
2153 }
2154
2155 $cssstring = '';
2156
2157 if (in_array($type, array('date', 'datetime', 'datetimegmt',))) {
2158 $cssstring = "center";
2159 } elseif (in_array($type, array('int', 'price', 'double'))) {
2160 $cssstring = "right";
2161 } elseif (in_array($type, array('boolean', 'radio', 'checkbox', 'ip', 'icon'))) {
2162 $cssstring = "center";
2163 }
2164
2165 if (!empty($this->attributes[$extrafieldsobjectkey]['csslist'][$key])) {
2166 $cssstring .= ($cssstring ? ' ' : '').$this->attributes[$extrafieldsobjectkey]['csslist'][$key];
2167 } else {
2168 if (in_array($type, array('ip'))) {
2169 $cssstring .= ($cssstring ? ' ' : '').'tdoverflowmax150';
2170 }
2171 }
2172
2173 return $cssstring;
2174 }
2175
2186 public function showSeparator($key, $object, $colspan = 2, $display_type = 'card', $mode = '')
2187 {
2188 global $conf, $langs;
2189
2190 $tagtype = 'tr';
2191 $tagtype_dyn = 'td';
2192
2193 if ($display_type == 'line') {
2194 $tagtype = 'div';
2195 $tagtype_dyn = 'span';
2196 $colspan = 0;
2197 }
2198
2199 $extrafield_param = $this->attributes[$object->table_element]['param'][$key];
2200 $extrafield_param_list = array();
2201 if (!empty($extrafield_param) && is_array($extrafield_param)) {
2202 $extrafield_param_list = array_keys($extrafield_param['options']);
2203 }
2204
2205 // Set $extrafield_collapse_display_value (do we have to collapse/expand the group after the separator)
2206 $extrafield_collapse_display_value = -1;
2207 $expand_display = false;
2208 if (is_array($extrafield_param_list) && count($extrafield_param_list) > 0) {
2209 $extrafield_collapse_display_value = intval($extrafield_param_list[0]);
2210 $expand_display = ((isset($_COOKIE['DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key]) || GETPOSTINT('ignorecollapsesetup')) ? (empty($_COOKIE['DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key]) ? false : true) : ($extrafield_collapse_display_value == 2 ? false : true));
2211 }
2212 $disabledcookiewrite = 0;
2213 if ($mode == 'create') {
2214 // On create mode, force separator group to not be collapsible
2215 $extrafield_collapse_display_value = 1;
2216 $expand_display = true; // We force group to be shown expanded
2217 $disabledcookiewrite = 1; // We keep status of group unchanged into the cookie
2218 }
2219
2220 $out = '<'.$tagtype.' id="trextrafieldseparator'.$key.(!empty($object->id) ? '_'.$object->id : '').'" class="trextrafieldseparator trextrafieldseparator'.$key.(!empty($object->id) ? '_'.$object->id : '').'">';
2221 $out .= '<'.$tagtype_dyn.' '.(!empty($colspan) ? 'colspan="' . $colspan . '"' : '').'>';
2222 // Some js code will be injected here to manage the collapsing of extrafields
2223 // Output the picto
2224 $out .= '<span class="'.($extrafield_collapse_display_value ? 'cursorpointer ' : '').($extrafield_collapse_display_value == 0 ? 'fas fa-square opacitymedium' : 'far fa-'.(($expand_display ? 'minus' : 'plus').'-square')).'"></span>';
2225 $out .= '&nbsp;';
2226 $out .= '<strong>';
2227 $out .= $langs->trans($this->attributes[$object->table_element]['label'][$key]);
2228 $out .= '</strong>';
2229 $out .= '</'.$tagtype_dyn.'>';
2230 $out .= '</'.$tagtype.'>';
2231
2232 $collapse_group = $key.(!empty($object->id) ? '_'.$object->id : '');
2233 //$extrafields_collapse_num = $this->attributes[$object->table_element]['pos'][$key].(!empty($object->id)?'_'.$object->id:'');
2234
2235 if ($extrafield_collapse_display_value == 1 || $extrafield_collapse_display_value == 2) {
2236 // Set the collapse_display status to cookie in priority or if ignorecollapsesetup is 1, if cookie and ignorecollapsesetup not defined, use the setup.
2237 $this->expand_display[$collapse_group] = $expand_display;
2238
2239 if (!empty($conf->use_javascript_ajax)) {
2240 $out .= '<!-- Add js script to manage the collapse/uncollapse of extrafields separators '.$key.' -->'."\n";
2241 $out .= '<script nonce="'.getNonce().'" type="text/javascript">'."\n";
2242 $out .= 'jQuery(document).ready(function(){'."\n";
2243 if (empty($disabledcookiewrite)) {
2244 if ($expand_display === false) {
2245 $out .= ' console.log("Inject js for the collapsing of extrafield '.$key.' - hide");'."\n";
2246 $out .= ' jQuery(".trextrafields_collapse'.$collapse_group.'").hide();'."\n";
2247 } else {
2248 $out .= ' console.log("Inject js for collapsing of extrafield '.$key.' - keep visible and set cookie");'."\n";
2249 $out .= ' document.cookie = "DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.'=1; path='.$_SERVER["PHP_SELF"].'"'."\n";
2250 }
2251 }
2252 $out .= ' jQuery("#trextrafieldseparator'.$key.(!empty($object->id) ? '_'.$object->id : '').'").click(function(){'."\n";
2253 $out .= ' console.log("We click on collapse/uncollapse to hide/show .trextrafields_collapse'.$collapse_group.'");'."\n";
2254 $out .= ' jQuery(".trextrafields_collapse'.$collapse_group.'").toggle(100, function(){'."\n";
2255 $out .= ' if (jQuery(".trextrafields_collapse'.$collapse_group.'").is(":hidden")) {'."\n";
2256 $out .= ' jQuery("#trextrafieldseparator'.$key.(!empty($object->id) ? '_'.$object->id : '').' '.$tagtype_dyn.' span").addClass("fa-plus-square").removeClass("fa-minus-square");'."\n";
2257 $out .= ' document.cookie = "DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.'=0; path='.$_SERVER["PHP_SELF"].'"'."\n";
2258 $out .= ' } else {'."\n";
2259 $out .= ' jQuery("#trextrafieldseparator'.$key.(!empty($object->id) ? '_'.$object->id : '').' '.$tagtype_dyn.' span").addClass("fa-minus-square").removeClass("fa-plus-square");'."\n";
2260 $out .= ' document.cookie = "DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.'=1; path='.$_SERVER["PHP_SELF"].'"'."\n";
2261 $out .= ' }'."\n";
2262 $out .= ' });'."\n";
2263 $out .= ' });'."\n";
2264 $out .= '});'."\n";
2265 $out .= '</script>'."\n";
2266 }
2267 } else {
2268 $this->expand_display[$collapse_group] = 1;
2269 }
2270
2271 return $out;
2272 }
2273
2285 public function setOptionalsFromPost($extralabels, &$object, $onlykey = '', $todefaultifmissing = 0)
2286 {
2287 global $langs;
2288
2289 $nofillrequired = 0; // For error when required field left blank
2290 $error_field_required = array();
2291
2292 if (isset($this->attributes[$object->table_element]['label']) && is_array($this->attributes[$object->table_element]['label'])) {
2293 $extralabels = $this->attributes[$object->table_element]['label'];
2294 }
2295
2296 if (is_array($extralabels)) {
2297 // Get extra fields
2298 foreach ($extralabels as $key => $value) {
2299 if (!empty($onlykey) && $onlykey != '@GETPOSTISSET' && $key != $onlykey) {
2300 continue;
2301 }
2302
2303 if (!empty($onlykey) && $onlykey == '@GETPOSTISSET' && !GETPOSTISSET('options_'.$key) && (! in_array($this->attributes[$object->table_element]['type'][$key], array('boolean', 'checkbox', 'chkbxlst', 'point', 'multipts', 'linestrg', 'polygon')))) {
2304 //when unticking boolean field, it's not set in POST
2305 continue;
2306 }
2307
2308 $key_type = $this->attributes[$object->table_element]['type'][$key];
2309 if ($key_type == 'separate') {
2310 continue;
2311 }
2312
2313 $enabled = 1;
2314 if (isset($this->attributes[$object->table_element]['enabled'][$key])) { // 'enabled' is often a condition on module enabled or not
2315 $enabled = (int) dol_eval($this->attributes[$object->table_element]['enabled'][$key], 1, 1, '2');
2316 }
2317
2318 $visibility = 1;
2319 if (isset($this->attributes[$object->table_element]['list'][$key])) { // 'list' is option for visibility
2320 $visibility = (int) dol_eval($this->attributes[$object->table_element]['list'][$key], 1, 1, '2');
2321 }
2322
2323 $perms = 1;
2324 if (isset($this->attributes[$object->table_element]['perms'][$key])) {
2325 $perms = (int) dol_eval($this->attributes[$object->table_element]['perms'][$key], 1, 1, '2');
2326 }
2327 if (empty($enabled)
2328 || (
2329 $onlykey === '@GETPOSTISSET'
2330 && in_array($this->attributes[$object->table_element]['type'][$key], array('boolean', 'checkbox', 'chkbxlst'))
2331 && in_array(abs($enabled), array(2, 5))
2332 && ! GETPOSTISSET('options_' . $key) // Update hidden checkboxes and multiselect only if they are provided
2333 )
2334 ) {
2335 continue;
2336 }
2337
2338 $visibility_abs = abs($visibility);
2339 // not modify if extra field is not in update form (0 : never, 2 or -2 : list only, 5 or - 5 : list and view only)
2340 if (empty($visibility_abs) || $visibility_abs == 2 || $visibility_abs == 5) {
2341 continue;
2342 }
2343 if (empty($perms)) {
2344 continue;
2345 }
2346
2347 if ($this->attributes[$object->table_element]['required'][$key]) { // Value is required
2348 // Check if functionally empty without using GETPOST (depending on the type of extrafield, a
2349 // technically non-empty value may be treated as empty functionally).
2350 // value can be alpha, int, array, etc...
2351 $v = $_POST["options_".$key] ?? null;
2352 $type = $this->attributes[$object->table_element]['type'][$key];
2353 if (self::isEmptyValue($v, $type)) {
2354 //print 'ccc'.$value.'-'.$this->attributes[$object->table_element]['required'][$key];
2355
2356 // Field is not defined. We mark this as an error. We may fix it later if there is a default value and $todefaultifmissing is set.
2357
2358 $nofillrequired++;
2359 if (!empty($this->attributes[$object->table_element]['langfile'][$key])) {
2360 $langs->load($this->attributes[$object->table_element]['langfile'][$key]);
2361 }
2362 $error_field_required[$key] = $langs->transnoentitiesnoconv($value);
2363 }
2364 }
2365
2366 if (in_array($key_type, array('date'))) {
2367 // Clean parameters
2368 $value_key = dol_mktime(12, 0, 0, GETPOSTINT("options_".$key."month"), GETPOSTINT("options_".$key."day"), GETPOSTINT("options_".$key."year"));
2369 } elseif (in_array($key_type, array('datetime'))) {
2370 // Clean parameters
2371 $value_key = dol_mktime(GETPOSTINT("options_".$key."hour"), GETPOSTINT("options_".$key."min"), GETPOSTINT("options_".$key."sec"), GETPOSTINT("options_".$key."month"), GETPOSTINT("options_".$key."day"), GETPOSTINT("options_".$key."year"), 'tzuserrel');
2372 } elseif (in_array($key_type, array('datetimegmt'))) {
2373 // Clean parameters
2374 $value_key = dol_mktime(GETPOSTINT("options_".$key."hour"), GETPOSTINT("options_".$key."min"), GETPOSTINT("options_".$key."sec"), GETPOSTINT("options_".$key."month"), GETPOSTINT("options_".$key."day"), GETPOSTINT("options_".$key."year"), 'gmt');
2375 } elseif (in_array($key_type, array('checkbox', 'chkbxlst'))) {
2376 $value_arr = GETPOST("options_".$key, 'array'); // check if an array
2377 if (!empty($value_arr)) {
2378 $value_key = implode(',', $value_arr);
2379 } else {
2380 $value_key = '';
2381 }
2382 } elseif (in_array($key_type, array('price', 'double'))) {
2383 $value_arr = GETPOST("options_".$key, 'alpha');
2384 $value_key = price2num($value_arr);
2385 } elseif (in_array($key_type, array('pricecy', 'double'))) {
2386 $value_key = price2num(GETPOST("options_".$key, 'alpha')).':'.GETPOST("options_".$key."currency_id", 'alpha');
2387 } elseif (in_array($key_type, array('html'))) {
2388 $value_key = GETPOST("options_".$key, 'restricthtml');
2389 } elseif (in_array($key_type, ['point', 'multipts', 'linestrg', 'polygon'])) {
2390 // construct point
2391 require_once DOL_DOCUMENT_ROOT.'/core/class/dolgeophp.class.php';
2392 $geojson = GETPOST("options_".$key, 'restricthtml');
2393 if ($geojson != '{}') {
2394 $dolgeophp = new DolGeoPHP($this->db);
2395 $value_key = $dolgeophp->getWkt($geojson);
2396 } else {
2397 $value_key = '';
2398 }
2399 } elseif (in_array($key_type, array('text'))) {
2400 $label_security_check = 'alphanohtml';
2401 // by default 'alphanohtml' (better security); hidden conf MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML allows basic html
2402 if (getDolGlobalString('MAIN_SECURITY_ALLOW_UNSECURED_REF_LABELS')) {
2403 $label_security_check = 'nohtml';
2404 } else {
2405 $label_security_check = !getDolGlobalString('MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML') ? 'alphanohtml' : 'restricthtml';
2406 }
2407 $value_key = GETPOST("options_".$key, $label_security_check);
2408 } else {
2409 $value_key = GETPOST("options_".$key);
2410 if (in_array($key_type, array('link')) && $value_key == '-1') {
2411 $value_key = '';
2412 }
2413 }
2414
2415 if (!empty($error_field_required[$key]) && $todefaultifmissing) {
2416 // Value is required but we have a default value and we asked to set empty value to the default value
2417 if (!empty($this->attributes[$object->table_element]['default']) && !is_null($this->attributes[$object->table_element]['default'][$key])) {
2418 $value_key = $this->attributes[$object->table_element]['default'][$key];
2419 unset($error_field_required[$key]);
2420 $nofillrequired--;
2421 }
2422 }
2423
2424 $object->array_options["options_".$key] = $value_key;
2425 }
2426
2427 if ($nofillrequired) {
2428 $langs->load('errors');
2429 $this->error = $langs->trans('ErrorFieldsRequired').' : '.implode(', ', $error_field_required);
2430 setEventMessages($this->error, null, 'errors');
2431 return -1;
2432 } else {
2433 return 1;
2434 }
2435 } else {
2436 return 0;
2437 }
2438 }
2439
2448 public function getOptionalsFromPost($extrafieldsobjectkey, $keysuffix = '', $keyprefix = '')
2449 {
2450 global $_POST;
2451
2452 if (is_string($extrafieldsobjectkey) && !empty($this->attributes[$extrafieldsobjectkey]['label']) && is_array($this->attributes[$extrafieldsobjectkey]['label'])) {
2453 $extralabels = $this->attributes[$extrafieldsobjectkey]['label'];
2454 } else {
2455 $extralabels = $extrafieldsobjectkey;
2456 }
2457
2458 if (is_array($extralabels)) {
2459 $array_options = array();
2460
2461 // Get extra fields
2462 foreach ($extralabels as $key => $value) {
2463 $key_type = '';
2464 if (is_string($extrafieldsobjectkey)) {
2465 $key_type = $this->attributes[$extrafieldsobjectkey]['type'][$key];
2466 }
2467
2468 if (in_array($key_type, array('date'))) {
2469 $dateparamname_start = $keyprefix . 'options_' . $key . $keysuffix . '_start';
2470 $dateparamname_end = $keyprefix . 'options_' . $key . $keysuffix . '_end';
2471
2472 if (GETPOST($dateparamname_start . 'year') || GETPOST($dateparamname_end . 'year')) {
2473 $value_key = array();
2474 // values provided as a component year, month, day, etc.
2475 if (GETPOST($dateparamname_start . 'year')) {
2476 $value_key['start'] = dol_mktime(0, 0, 0, GETPOSTINT($dateparamname_start . 'month'), GETPOSTINT($dateparamname_start . 'day'), GETPOSTINT($dateparamname_start . 'year'));
2477 }
2478 if (GETPOST($dateparamname_end . 'year')) {
2479 $value_key['end'] = dol_mktime(23, 59, 59, GETPOSTINT($dateparamname_end . 'month'), GETPOSTINT($dateparamname_end . 'day'), GETPOSTINT($dateparamname_end . 'year'));
2480 }
2481 } elseif (GETPOST($keyprefix."options_".$key.$keysuffix."year")) {
2482 // Clean parameters
2483 $value_key = dol_mktime(12, 0, 0, GETPOSTINT($keyprefix."options_".$key.$keysuffix."month"), GETPOSTINT($keyprefix."options_".$key.$keysuffix."day"), GETPOSTINT($keyprefix."options_".$key.$keysuffix."year"));
2484 } else {
2485 continue; // Value was not provided, we should not set it.
2486 }
2487 } elseif (in_array($key_type, array('datetime', 'datetimegmt'))) {
2488 $dateparamname_start = $keyprefix . 'options_' . $key . $keysuffix . '_start';
2489 $dateparamname_end = $keyprefix . 'options_' . $key . $keysuffix . '_end';
2490
2491 if (GETPOST($dateparamname_start . 'year') || GETPOST($dateparamname_end . 'year')) {
2492 // values provided as a date pair (start date + end date), each date being broken down as year, month, day, etc.
2493 $dateparamname_start_hour = GETPOSTINT($dateparamname_start . 'hour') != '-1' ? GETPOSTINT($dateparamname_start . 'hour') : '00';
2494 $dateparamname_start_min = GETPOSTINT($dateparamname_start . 'min') != '-1' ? GETPOSTINT($dateparamname_start . 'min') : '00';
2495 $dateparamname_start_sec = GETPOSTINT($dateparamname_start . 'sec') != '-1' ? GETPOSTINT($dateparamname_start . 'sec') : '00';
2496 $dateparamname_end_hour = GETPOSTINT($dateparamname_end . 'hour') != '-1' ? GETPOSTINT($dateparamname_end . 'hour') : '23';
2497 $dateparamname_end_min = GETPOSTINT($dateparamname_end . 'min') != '-1' ? GETPOSTINT($dateparamname_end . 'min') : '59';
2498 $dateparamname_end_sec = GETPOSTINT($dateparamname_end . 'sec') != '-1' ? GETPOSTINT($dateparamname_end . 'sec') : '59';
2499 if ($key_type == 'datetimegmt') {
2500 $value_key = array(
2501 'start' => dol_mktime($dateparamname_start_hour, $dateparamname_start_min, $dateparamname_start_sec, GETPOSTINT($dateparamname_start . 'month'), GETPOSTINT($dateparamname_start . 'day'), GETPOSTINT($dateparamname_start . 'year'), 'gmt'),
2502 'end' => dol_mktime($dateparamname_end_hour, $dateparamname_end_min, $dateparamname_end_sec, GETPOSTINT($dateparamname_end . 'month'), GETPOSTINT($dateparamname_end . 'day'), GETPOSTINT($dateparamname_end . 'year'), 'gmt')
2503 );
2504 } else {
2505 $value_key = array(
2506 'start' => dol_mktime($dateparamname_start_hour, $dateparamname_start_min, $dateparamname_start_sec, GETPOSTINT($dateparamname_start . 'month'), GETPOSTINT($dateparamname_start . 'day'), GETPOSTINT($dateparamname_start . 'year'), 'tzuserrel'),
2507 'end' => dol_mktime($dateparamname_end_hour, $dateparamname_end_min, $dateparamname_end_sec, GETPOSTINT($dateparamname_end . 'month'), GETPOSTINT($dateparamname_end . 'day'), GETPOSTINT($dateparamname_end . 'year'), 'tzuserrel')
2508 );
2509 }
2510 } elseif (GETPOST($keyprefix."options_".$key.$keysuffix."year")) {
2511 // Clean parameters
2512 if ($key_type == 'datetimegmt') {
2513 $value_key = dol_mktime(GETPOSTINT($keyprefix."options_".$key.$keysuffix."hour"), GETPOSTINT($keyprefix."options_".$key.$keysuffix."min"), GETPOSTINT($keyprefix."options_".$key.$keysuffix."sec"), GETPOSTINT($keyprefix."options_".$key.$keysuffix."month"), GETPOSTINT($keyprefix."options_".$key.$keysuffix."day"), GETPOSTINT($keyprefix."options_".$key.$keysuffix."year"), 'gmt');
2514 } else {
2515 $value_key = dol_mktime(GETPOSTINT($keyprefix."options_".$key.$keysuffix."hour"), GETPOSTINT($keyprefix."options_".$key.$keysuffix."min"), GETPOSTINT($keyprefix."options_".$key.$keysuffix."sec"), GETPOSTINT($keyprefix."options_".$key.$keysuffix."month"), GETPOSTINT($keyprefix."options_".$key.$keysuffix."day"), GETPOSTINT($keyprefix."options_".$key.$keysuffix."year"), 'tzuserrel');
2516 }
2517 } else {
2518 continue; // Value was not provided, we should not set it.
2519 }
2520 } elseif ($key_type == 'select') {
2521 // to detect if we are in search context
2522 if (GETPOSTISARRAY($keyprefix."options_".$key.$keysuffix)) {
2523 $value_arr = GETPOST($keyprefix."options_".$key.$keysuffix, 'array:aZ09');
2524 // Make sure we get an array even if there's only one selected
2525 $value_arr = (array) $value_arr;
2526 $value_key = implode(',', $value_arr);
2527 } else {
2528 $value_key = GETPOST($keyprefix."options_".$key.$keysuffix);
2529 }
2530 } elseif (in_array($key_type, array('checkbox', 'chkbxlst'))) {
2531 // We test on a hidden field named "..._multiselect" that is always set to 1 if param is in form so
2532 // when nothing is provided we can make a difference between noparam in the form and param was set to nothing.
2533 if (!GETPOSTISSET($keyprefix."options_".$key.$keysuffix.'_multiselect')) {
2534 continue; // Value was not provided, we should not set it.
2535 }
2536 $value_arr = GETPOST($keyprefix."options_".$key.$keysuffix);
2537 // Make sure we get an array even if there's only one checkbox
2538 $value_arr = (array) $value_arr;
2539 $value_key = implode(',', $value_arr);
2540 } elseif (in_array($key_type, array('price', 'double', 'int'))) {
2541 if (!GETPOSTISSET($keyprefix."options_".$key.$keysuffix)) {
2542 continue; // Value was not provided, we should not set it.
2543 }
2544 $value_arr = GETPOST($keyprefix."options_".$key.$keysuffix);
2545 if ($keyprefix != 'search_') { // If value is for a search, we must keep complex string like '>100 <=150'
2546 $value_key = price2num($value_arr);
2547 } else {
2548 $value_key = $value_arr;
2549 }
2550 } elseif (in_array($key_type, array('boolean'))) {
2551 // We test on a hidden field named "..._boolean" that is always set to 1 if param is in form so
2552 // when nothing is provided we can make a difference between noparam in the form and param was set to nothing.
2553 if (!GETPOSTISSET($keyprefix."options_".$key.$keysuffix."_boolean")) {
2554 $value_key = '';
2555 } else {
2556 $value_arr = GETPOST($keyprefix."options_".$key.$keysuffix);
2557 $value_key = $value_arr;
2558 }
2559 } elseif (in_array($key_type, array('html'))) {
2560 if (!GETPOSTISSET($keyprefix."options_".$key.$keysuffix)) {
2561 continue; // Value was not provided, we should not set it.
2562 }
2563 $value_key = dol_htmlcleanlastbr(GETPOST($keyprefix."options_".$key.$keysuffix, 'restricthtml'));
2564 } else {
2565 if (!GETPOSTISSET($keyprefix."options_".$key.$keysuffix)) {
2566 continue; // Value was not provided, we should not set it.
2567 }
2568 $value_key = GETPOST($keyprefix."options_".$key.$keysuffix);
2569 }
2570
2571 $array_options[$keyprefix."options_".$key] = $value_key; // No keyprefix here. keyprefix is used only for read.
2572 }
2573
2574 return $array_options;
2575 }
2576
2577 return 0;
2578 }
2579
2585 public static function getListOfTypesLabels()
2586 {
2587 global $langs;
2588
2589 $arraytype2label = array('');
2590
2591 $tmptype2label = ExtraFields::$type2label;
2592 foreach ($tmptype2label as $key => $val) {
2593 $arraytype2label[$key] = $langs->transnoentitiesnoconv($val);
2594 }
2595
2596 if (!getDolGlobalString('MAIN_USE_EXTRAFIELDS_ICON')) {
2597 unset($arraytype2label['icon']);
2598 }
2599 if (!getDolGlobalString('MAIN_USE_GEOPHP')) {
2600 unset($arraytype2label['point']);
2601 unset($arraytype2label['multipts']);
2602 unset($arraytype2label['linestrg']);
2603 unset($arraytype2label['polygon']);
2604 }
2605
2606 return $arraytype2label;
2607 }
2608
2616 public static function isEmptyValue($v, string $type)
2617 {
2618 if ($v === null || $v === '') {
2619 return true;
2620 }
2621 if (is_array($v) || $type == 'select') {
2622 return empty($v);
2623 }
2624 if ($type == 'link') {
2625 return ($v == '-1');
2626 }
2627 if ($type == 'sellist') {
2628 return ($v == '0');
2629 }
2630 return (empty($v) && $v != '0');
2631 }
2632}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:456
Class to manage categories.
Class to manage a WYSIWYG editor.
Class to manage Geo processing Usage: $dolgeophp=new DolGeoPHP($db);.
Class to manage standard extra fields.
update_label($attrname, $label, $type, $size, $elementtype, $unique=0, $required=0, $pos=0, $param=array(), $alwayseditable=0, $perms='', $list='0', $help='', $default='', $computed='', $entity='', $langfile='', $enabled='1', $totalizable=0, $printable=0, $moreparams=array())
Modify description of personalized attribute This is a private method.
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', $totalizable=0, $printable=0, $moreparams=array())
Add a new extra field parameter.
getAlignFlag($key, $extrafieldsobjectkey='')
Return the CSS to use for this extrafield into list.
getOptionalsFromPost($extrafieldsobjectkey, $keysuffix='', $keyprefix='')
return array_options array of data of extrafields value of object sent by a search form
create_label($attrname, $label='', $type='', $pos=0, $size='', $elementtype='', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list='-1', $help='', $default='', $computed='', $entity='', $langfile='', $enabled='1', $totalizable=0, $printable=0, $moreparams=array())
Add description of a new optional attribute.
showInputField($key, $value, $moreparam='', $keysuffix='', $keyprefix='', $morecss='', $objectid=0, $extrafieldsobjectkey='', $mode=0)
Return HTML string to put an input field into a page Code very similar with showInputField of common ...
fetch_name_optionals_label($elementtype, $forceload=false, $attrname='')
Load the array of extrafields definition $this->attributes.
create($attrname, $type='varchar', $length='255', $elementtype='', $unique=0, $required=0, $default_value='', $param=array(), $perms='', $list='0', $computed='', $help='', $moreparams=array())
Add a new optional attribute.
showSeparator($key, $object, $colspan=2, $display_type='card', $mode='')
Return HTML string to print separator extrafield.
update($attrname, $label, $type, $length, $elementtype, $unique=0, $required=0, $pos=0, $param=array(), $alwayseditable=0, $perms='', $list='', $help='', $default='', $computed='', $entity='', $langfile='', $enabled='1', $totalizable=0, $printable=0, $moreparams=array())
Modify type of a personalized attribute.
static getListOfTypesLabels()
Return array with all possible types and labels of extrafields.
showOutputField($key, $value, $moreparam='', $extrafieldsobjectkey='', $outputlangs=null)
Return HTML string to put an output field into a page.
updateExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param='', $alwayseditable=0, $perms='', $list='-1', $help='', $computed='', $entity='', $langfile='', $enabled='1', $totalizable=0, $printable=0, $moreparams=array())
Update an existing extra field parameter.
__construct($db)
Constructor.
delete_label($attrname, $elementtype='')
Delete description of an optional attribute.
setOptionalsFromPost($extralabels, &$object, $onlykey='', $todefaultifmissing=0)
Fill array_options property of object by extrafields value (using for data sent by forms)
static isEmptyValue($v, string $type)
Return if a value is "empty" for a mandatory vision.
Class to manage generation of HTML components Only common components must be here.
Class to manage a Leaflet map width geometrics objects.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_print_phone($phone, $countrycode='', $cid=0, $socid=0, $addlink='', $separ="&nbsp;", $withpicto='', $titlealt='', $adddivfloat=0, $morecss='')
Format phone numbers according to country.
dol_print_ip($ip, $mode=0)
Return an IP formatted to be shown on screen.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
yn($yesno, $case=1, $color=0)
Return yes or no in current language.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
dol_print_url($url, $target='_blank', $max=32, $withpicto=0, $morecss='')
Show Url link.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_print_email($email, $cid=0, $socid=0, $addlink=0, $max=64, $showinvalid=1, $withpicto=0)
Show EMail link formatted for HTML output.
GETPOSTISARRAY($paramname, $method=0)
Return true if the parameter $paramname is submit from a POST OR GET as an array.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
dol_htmlcleanlastbr($stringtodecode)
This function remove all ending and br at end.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
jsonOrUnserialize($stringtodecode)
Decode an encode string.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...