dolibarr 21.0.0-alpha
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 'select' => 'ExtrafieldSelect',
94 'sellist' => 'ExtrafieldSelectList',
95 'radio' => 'ExtrafieldRadio',
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 dol_syslog(get_class($this).'::showInputField type=chkbxlst', LOG_DEBUG);
1623 $resql = $this->db->query($sql);
1624 if ($resql) {
1625 $num = $this->db->num_rows($resql);
1626 $i = 0;
1627
1628 $data = array();
1629
1630 while ($i < $num) {
1631 $labeltoshow = '';
1632 $obj = $this->db->fetch_object($resql);
1633
1634 $notrans = false;
1635 // Several field into label (eq table:code|label:rowid)
1636 $fields_label = explode('|', $InfoFieldList[1]);
1637 if (is_array($fields_label)) {
1638 $notrans = true;
1639 foreach ($fields_label as $field_toshow) {
1640 $labeltoshow .= $obj->$field_toshow.' ';
1641 }
1642 } else {
1643 $labeltoshow = $obj->{$InfoFieldList[1]};
1644 }
1645 $labeltoshow = dol_trunc($labeltoshow, 45);
1646
1647 if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1648 $labeltoshow = '';
1649 foreach ($fields_label as $field_toshow) {
1650 $translabel = $langs->trans($obj->$field_toshow);
1651 if ($translabel != $obj->$field_toshow) {
1652 $labeltoshow .= ' '.dol_trunc($translabel, 18).' ';
1653 } else {
1654 $labeltoshow .= ' '.dol_trunc($obj->$field_toshow, 18).' ';
1655 }
1656 }
1657 $data[$obj->rowid] = $labeltoshow;
1658 } else {
1659 if (!$notrans) {
1660 $translabel = $langs->trans($obj->{$InfoFieldList[1]});
1661 if ($translabel != $obj->{$InfoFieldList[1]}) {
1662 $labeltoshow = dol_trunc($translabel, 18);
1663 } else {
1664 $labeltoshow = dol_trunc($obj->{$InfoFieldList[1]}, 18);
1665 }
1666 }
1667 if (empty($labeltoshow)) {
1668 $labeltoshow = '(not defined)';
1669 }
1670
1671 if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1672 $data[$obj->rowid] = $labeltoshow;
1673 }
1674
1675 if (!empty($InfoFieldList[3]) && $parentField) {
1676 $parent = $parentName.':'.$obj->{$parentField};
1677 }
1678
1679 $data[$obj->rowid] = $labeltoshow;
1680 }
1681
1682 $i++;
1683 }
1684 $this->db->free($resql);
1685
1686 $out = $form->multiselectarray($keyprefix.$key.$keysuffix, $data, $value_arr, '', 0, '', 0, '100%');
1687 } else {
1688 print 'Error in request '.$sql.' '.$this->db->lasterror().'. Check setup of extra parameters.<br>';
1689 }
1690 } else {
1691 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1692 $data = $form->select_all_categories(Categorie::$MAP_ID_TO_CODE[$InfoFieldList[5]], '', 'parent', 64, $InfoFieldList[6], 1, 1);
1693 $out = $form->multiselectarray($keyprefix.$key.$keysuffix, $data, $value_arr, '', 0, '', 0, '100%');
1694 }
1695 }
1696 } elseif ($type == 'link') {
1697 $param_list = array_keys($param['options']); // $param_list[0] = 'ObjectName:classPath' but can also be 'ObjectName:classPath:1:(status:=:1)'
1698 /* Removed.
1699 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
1700 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.
1701 if (strpos($param_list[0], '$ID$') !== false && !empty($objectid)) {
1702 $param_list[0] = str_replace('$ID$', $objectid, $param_list[0]);
1703 }*/
1704 $showempty = (($required && $default != '') ? 0 : 1);
1705
1706 $tmparray = explode(':', $param_list[0]);
1707
1708 $element = $extrafieldsobjectkey; // $extrafieldsobjectkey comes from $object->table_element but we need $object->element
1709 if ($element == 'socpeople') {
1710 $element = 'contact';
1711 } elseif ($element == 'projet') {
1712 $element = 'project';
1713 }
1714
1715 //$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
1716 $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.
1717 $objectfield = $element.':options_'.$key; // Example: 'actioncomm:options_fff' To be used in priority to know object linked with all its definition (including filters)
1718
1719 $out = $form->selectForForms($objectdesc, $keyprefix.$key.$keysuffix, $value, $showempty, '', '', $morecss, '', 0, 0, '', $objectfield);
1720 } elseif (in_array($type, ['point', 'multipts', 'linestrg', 'polygon'])) {
1721 require_once DOL_DOCUMENT_ROOT.'/core/class/dolgeophp.class.php';
1722 $dolgeophp = new DolGeoPHP($this->db);
1723 $geojson = '{}';
1724 $centroidjson = getDolGlobalString('MAIN_INFO_SOCIETE_GEO_COORDINATES', '{}');
1725 if (!empty($value)) {
1726 $tmparray = $dolgeophp->parseGeoString($value);
1727 $geojson = $tmparray['geojson'];
1728 $centroidjson = $tmparray['centroidjson'];
1729 }
1730 if (!preg_match('/search_/', $keyprefix)) {
1731 require_once DOL_DOCUMENT_ROOT.'/core/class/geomapeditor.class.php';
1732 $geomapeditor = new GeoMapEditor();
1733 $out .= $geomapeditor->getHtml($keyprefix.$key.$keysuffix, $geojson, $centroidjson, $type);
1734 } else {
1735 // If keyprefix is search_ or search_options_, we must just use a simple text field
1736 $out = '';
1737 }
1738 } elseif ($type == 'password') {
1739 // If prefix is 'search_', field is used as a filter, we use a common text field.
1740 $out = '<input style="display:none" type="text" name="fakeusernameremembered">'; // Hidden field to reduce impact of evil Google Chrome autopopulate bug.
1741 $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 : '').'>';
1742 }
1743 if (!empty($hidden)) {
1744 $out = '<input type="hidden" value="'.$value.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'"/>';
1745 }
1746 /* Add comments
1747 if ($type == 'date') $out.=' (YYYY-MM-DD)';
1748 elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)';
1749 */
1750 /*if (!empty($help) && $keyprefix != 'search_options_') {
1751 $out .= $form->textwithpicto('', $help, 1, 'help', '', 0, 3);
1752 }*/
1753 return $out;
1754 }
1755
1756
1767 public function showOutputField($key, $value, $moreparam = '', $extrafieldsobjectkey = '', $outputlangs = null)
1768 {
1769 global $conf, $langs;
1770
1771 if (is_null($outputlangs) || !is_object($outputlangs)) {
1772 $outputlangs = $langs;
1773 }
1774
1775 if (empty($extrafieldsobjectkey)) {
1776 dol_syslog(get_class($this).'::showOutputField extrafieldsobjectkey required', LOG_ERR);
1777 return 'BadValueForParamExtraFieldsObjectKey';
1778 }
1779
1780 $label = $this->attributes[$extrafieldsobjectkey]['label'][$key];
1781 $type = $this->attributes[$extrafieldsobjectkey]['type'][$key];
1782 $size = $this->attributes[$extrafieldsobjectkey]['size'][$key]; // Can be '255', '24,8'...
1783 $default = $this->attributes[$extrafieldsobjectkey]['default'][$key];
1784 $computed = $this->attributes[$extrafieldsobjectkey]['computed'][$key];
1785 $unique = $this->attributes[$extrafieldsobjectkey]['unique'][$key];
1786 $required = $this->attributes[$extrafieldsobjectkey]['required'][$key];
1787 $param = $this->attributes[$extrafieldsobjectkey]['param'][$key];
1788 $perms = (int) dol_eval($this->attributes[$extrafieldsobjectkey]['perms'][$key], 1, 1, '2');
1789 $langfile = $this->attributes[$extrafieldsobjectkey]['langfile'][$key];
1790 $list = (string) dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1, 1, '2');
1791 $help = $this->attributes[$extrafieldsobjectkey]['help'][$key];
1792 $cssview = $this->attributes[$extrafieldsobjectkey]['cssview'][$key];
1793
1794 $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)
1795
1796 if ($hidden) {
1797 return ''; // This is a protection. If field is hidden, we should just not call this method.
1798 }
1799
1800 //if ($computed) $value = // $value is already calculated into $value before calling this method
1801
1802 $showsize = 0;
1803 if ($type == 'date') {
1804 $showsize = 10;
1805 if ($value !== '') {
1806 $value = dol_print_date($value, 'day'); // For date without hour, date is always GMT for storage and output
1807 }
1808 } elseif ($type == 'datetime') {
1809 $showsize = 19;
1810 if ($value !== '') {
1811 $value = dol_print_date($value, 'dayhour', 'tzuserrel');
1812 }
1813 } elseif ($type == 'datetimegmt') {
1814 $showsize = 19;
1815 if ($value !== '') {
1816 $value = dol_print_date($value, 'dayhour', 'gmt');
1817 }
1818 } elseif ($type == 'int') {
1819 $showsize = 10;
1820 } elseif ($type == 'double') {
1821 if (!empty($value)) {
1822 //$value=price($value);
1823 $sizeparts = explode(",", $size);
1824 $number_decimals = array_key_exists(1, $sizeparts) ? $sizeparts[1] : 0;
1825 $value = price($value, 0, $outputlangs, 0, 0, $number_decimals, '');
1826 }
1827 } elseif ($type == 'boolean') {
1828 $checked = '';
1829 if (!empty($value)) {
1830 $checked = ' checked ';
1831 }
1832 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER') < 2) {
1833 $value = '<input type="checkbox" '.$checked.' '.($moreparam ? $moreparam : '').' readonly disabled>';
1834 } else {
1835 $value = yn($value ? 1 : 0);
1836 }
1837 } elseif ($type == 'mail') {
1838 $value = dol_print_email($value, 0, 0, 0, 64, 1, 1);
1839 } elseif ($type == 'ip') {
1840 $value = dol_print_ip($value, 0);
1841 } elseif ($type == 'icon') {
1842 $value = '<span class="'.$value.'"></span>';
1843 } elseif ($type == 'url') {
1844 $value = dol_print_url($value, '_blank', 32, 1);
1845 } elseif ($type == 'phone') {
1846 $value = dol_print_phone($value, '', 0, 0, '', '&nbsp;', 'phone');
1847 } elseif ($type == 'price') {
1848 //$value = price($value, 0, $langs, 0, 0, -1, $conf->currency);
1849 if ($value || $value == '0') {
1850 $value = price($value, 0, $outputlangs, 0, $conf->global->MAIN_MAX_DECIMALS_TOT, -1).' '.$outputlangs->getCurrencySymbol($conf->currency);
1851 }
1852 } elseif ($type == 'pricecy') {
1853 $currency = $conf->currency;
1854 if (!empty($value)) {
1855 // $value in memory is a php string like '0.01:EUR'
1856 $pricetmp = explode(':', $value);
1857 $currency = !empty($pricetmp[1]) ? $pricetmp[1] : $conf->currency;
1858 $value = $pricetmp[0];
1859 }
1860 if ($value || $value == '0') {
1861 $value = price($value, 0, $outputlangs, 0, $conf->global->MAIN_MAX_DECIMALS_TOT, -1, $currency);
1862 }
1863 } elseif ($type == 'select') {
1864 $valstr = (!empty($param['options'][$value]) ? $param['options'][$value] : '');
1865 if (($pos = strpos($valstr, "|")) !== false) {
1866 $valstr = substr($valstr, 0, $pos);
1867 }
1868 if ($langfile && $valstr) {
1869 $value = $outputlangs->trans($valstr);
1870 } else {
1871 $value = $valstr;
1872 }
1873 } elseif ($type == 'sellist') {
1874 $param_list = array_keys($param['options']);
1875 $InfoFieldList = explode(":", $param_list[0]);
1876
1877 $selectkey = "rowid";
1878 $keyList = 'rowid';
1879
1880 if (count($InfoFieldList) >= 3) {
1881 $selectkey = $InfoFieldList[2];
1882 $keyList = $InfoFieldList[2].' as rowid';
1883 }
1884
1885 $fields_label = explode('|', $InfoFieldList[1]);
1886 if (is_array($fields_label)) {
1887 $keyList .= ', ';
1888 $keyList .= implode(', ', $fields_label);
1889 }
1890
1891 $filter_categorie = false;
1892 if (count($InfoFieldList) > 5) {
1893 if ($InfoFieldList[0] == 'categorie') {
1894 $filter_categorie = true;
1895 }
1896 }
1897
1898 $sql = "SELECT ".$keyList;
1899 $sql .= ' FROM '.$this->db->prefix().$InfoFieldList[0];
1900 if (!empty($InfoFieldList[4]) && strpos($InfoFieldList[4], 'extra.') !== false) {
1901 $sql .= ' as main';
1902 }
1903 if ($selectkey == 'rowid' && empty($value)) {
1904 $sql .= " WHERE ".$selectkey." = 0";
1905 } elseif ($selectkey == 'rowid') {
1906 $sql .= " WHERE ".$selectkey." = ".((int) $value);
1907 } else {
1908 $sql .= " WHERE ".$selectkey." = '".$this->db->escape($value)."'";
1909 }
1910
1911 //$sql.= ' AND entity = '.$conf->entity;
1912
1913 dol_syslog(get_class($this).':showOutputField:$type=sellist', LOG_DEBUG);
1914 $resql = $this->db->query($sql);
1915 if ($resql) {
1916 if ($filter_categorie === false) {
1917 $value = ''; // value was used, so now we reste it to use it to build final output
1918
1919 $obj = $this->db->fetch_object($resql);
1920
1921 // Several field into label (eq table:code|label:rowid)
1922 $fields_label = explode('|', $InfoFieldList[1]);
1923
1924 if (is_array($fields_label) && count($fields_label) > 1) {
1925 foreach ($fields_label as $field_toshow) {
1926 $translabel = '';
1927 if (!empty($obj->$field_toshow)) {
1928 $translabel = $outputlangs->trans($obj->$field_toshow);
1929
1930 if ($translabel != $obj->$field_toshow) {
1931 $value .= dol_trunc($translabel, 24) . ' ';
1932 } else {
1933 $value .= $obj->$field_toshow . ' ';
1934 }
1935 }
1936 }
1937 } else {
1938 $translabel = '';
1939 $tmppropname = $InfoFieldList[1];
1940 //$obj->$tmppropname = '';
1941 if (!empty(isset($obj->$tmppropname) ? $obj->$tmppropname : '')) {
1942 $translabel = $outputlangs->trans($obj->$tmppropname);
1943 }
1944 if ($translabel != (isset($obj->$tmppropname) ? $obj->$tmppropname : '')) {
1945 $value = dol_trunc($translabel, 18);
1946 } else {
1947 $value = isset($obj->$tmppropname) ? $obj->$tmppropname : '';
1948 }
1949 }
1950 } else {
1951 $toprint = array();
1952 $obj = $this->db->fetch_object($resql);
1953 if ($obj->rowid) {
1954 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1955 $c = new Categorie($this->db);
1956 $result = $c->fetch($obj->rowid);
1957 if ($result > 0) {
1958 $ways = $c->print_all_ways(); // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formatted text
1959 foreach ($ways as $way) {
1960 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories"' . ($c->color ? ' style="background: #' . $c->color . ';"' : ' style="background: #bbb"') . '>' . img_object('', 'category') . ' ' . $way . '</li>';
1961 }
1962 }
1963 }
1964 $value = '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
1965 }
1966 } else {
1967 dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING);
1968 }
1969 } elseif ($type == 'radio') {
1970 if (!isset($param['options'][$value])) {
1971 $outputlangs->load('errors');
1972 $value = $outputlangs->trans('ErrorNoValueForRadioType');
1973 } else {
1974 $value = $outputlangs->trans($param['options'][$value]);
1975 }
1976 } elseif ($type == 'checkbox') {
1977 $value_arr = explode(',', $value);
1978 $value = '';
1979 $toprint = array();
1980 if (is_array($value_arr)) {
1981 foreach ($value_arr as $keyval => $valueval) {
1982 if (!empty($valueval)) {
1983 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #bbb">'.$param['options'][$valueval].'</li>';
1984 }
1985 }
1986 }
1987 $value = '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
1988 } elseif ($type == 'chkbxlst') {
1989 $value_arr = explode(',', $value);
1990
1991 $param_list = array_keys($param['options']);
1992 $InfoFieldList = explode(":", $param_list[0]);
1993
1994 $selectkey = "rowid";
1995 $keyList = 'rowid';
1996
1997 if (count($InfoFieldList) >= 3) {
1998 $selectkey = $InfoFieldList[2];
1999 $keyList = $InfoFieldList[2].' as rowid';
2000 }
2001
2002 $fields_label = explode('|', $InfoFieldList[1]);
2003 if (is_array($fields_label)) {
2004 $keyList .= ', ';
2005 $keyList .= implode(', ', $fields_label);
2006 }
2007
2008 $filter_categorie = false;
2009 if (count($InfoFieldList) > 5) {
2010 if ($InfoFieldList[0] == 'categorie') {
2011 $filter_categorie = true;
2012 }
2013 }
2014
2015 $sql = "SELECT ".$keyList;
2016 $sql .= " FROM ".$this->db->prefix().$InfoFieldList[0];
2017 if (strpos($InfoFieldList[4], 'extra.') !== false) {
2018 $sql .= ' as main';
2019 }
2020 // $sql.= " WHERE ".$selectkey."='".$this->db->escape($value)."'";
2021 // $sql.= ' AND entity = '.$conf->entity;
2022
2023 dol_syslog(get_class($this).':showOutputField:$type=chkbxlst', LOG_DEBUG);
2024 $resql = $this->db->query($sql);
2025 if ($resql) {
2026 if ($filter_categorie === false) {
2027 $value = ''; // value was used, so now we reste it to use it to build final output
2028 $toprint = array();
2029 while ($obj = $this->db->fetch_object($resql)) {
2030 // Several field into label (eq table:code|label:rowid)
2031 $fields_label = explode('|', $InfoFieldList[1]);
2032 if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
2033 if (is_array($fields_label) && count($fields_label) > 1) {
2034 $label = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #bbb">';
2035 foreach ($fields_label as $field_toshow) {
2036 $translabel = '';
2037 if (!empty($obj->$field_toshow)) {
2038 $translabel = $outputlangs->trans($obj->$field_toshow);
2039 }
2040 if ($translabel != $field_toshow) {
2041 $label .= ' '.dol_trunc($translabel, 18);
2042 } else {
2043 $label .= ' '.$obj->$field_toshow;
2044 }
2045 }
2046 $label .= '</li>';
2047 $toprint[] = $label;
2048 } else {
2049 $translabel = '';
2050 if (!empty($obj->{$InfoFieldList[1]})) {
2051 $translabel = $outputlangs->trans($obj->{$InfoFieldList[1]});
2052 }
2053 if ($translabel != $obj->{$InfoFieldList[1]}) {
2054 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #bbb">'.dol_trunc($translabel, 18).'</li>';
2055 } else {
2056 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #bbb">'.$obj->{$InfoFieldList[1]}.'</li>';
2057 }
2058 }
2059 }
2060 }
2061 } else {
2062 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
2063
2064 $toprint = array();
2065 while ($obj = $this->db->fetch_object($resql)) {
2066 if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
2067 $c = new Categorie($this->db);
2068 $c->fetch($obj->rowid);
2069 $ways = $c->print_all_ways(); // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formatted text
2070 foreach ($ways as $way) {
2071 $toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories"'.($c->color ? ' style="background: #'.$c->color.';"' : ' style="background: #bbb"').'>'.img_object('', 'category').' '.$way.'</li>';
2072 }
2073 }
2074 }
2075 }
2076 if (!empty($toprint)) {
2077 $value = '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
2078 }
2079 } else {
2080 dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING);
2081 }
2082 } elseif ($type == 'link') {
2083 $out = '';
2084
2085 // Only if something to display (perf)
2086 if ($value) { // If we have -1 here, pb is into insert, not into output (fix insert instead of changing code here to compensate)
2087 $param_list = array_keys($param['options']); // $param_list='ObjectName:classPath'
2088
2089 $InfoFieldList = explode(":", $param_list[0]);
2090 $classname = $InfoFieldList[0];
2091 $classpath = $InfoFieldList[1];
2092 if (!empty($classpath)) {
2093 dol_include_once($InfoFieldList[1]);
2094 if ($classname && class_exists($classname)) {
2095 $object = new $classname($this->db);
2096 $object->fetch($value);
2097 $value = $object->getNomUrl(3);
2098 }
2099 } else {
2100 dol_syslog('Error bad setup of extrafield', LOG_WARNING);
2101 return 'Error bad setup of extrafield';
2102 }
2103 }
2104 } elseif ($type == 'point') {
2105 if (!empty($value)) {
2106 require_once DOL_DOCUMENT_ROOT.'/core/class/dolgeophp.class.php';
2107 $dolgeophp = new DolGeoPHP($this->db);
2108 $value = $dolgeophp->getXYString($value);
2109 } else {
2110 $value = '';
2111 }
2112 } elseif (in_array($type, ['multipts','linestrg', 'polygon'])) {
2113 if (!empty($value)) {
2114 require_once DOL_DOCUMENT_ROOT.'/core/class/dolgeophp.class.php';
2115 $dolgeophp = new DolGeoPHP($this->db);
2116 $value = $dolgeophp->getPointString($value);
2117 } else {
2118 $value = '';
2119 }
2120 } elseif ($type == 'text') {
2121 $value = '<div class="'.($cssview ? $cssview : 'shortmessagecut').'">'.dol_htmlentitiesbr($value).'</div>';
2122 } elseif ($type == 'html') {
2123 $value = dol_htmlentitiesbr($value);
2124 } elseif ($type == 'password') {
2125 $value = dol_trunc(preg_replace('/./i', '*', $value), 8, 'right', 'UTF-8', 1);
2126 } else {
2127 $showsize = round((float) $size);
2128 if ($showsize > 48) {
2129 $showsize = 48;
2130 }
2131 }
2132
2133 //print $type.'-'.$size;
2134 $out = $value;
2135
2136 return $out;
2137 }
2138
2146 public function getAlignFlag($key, $extrafieldsobjectkey = '')
2147 {
2148 $type = 'varchar';
2149 if (!empty($extrafieldsobjectkey)) {
2150 $type = $this->attributes[$extrafieldsobjectkey]['type'][$key];
2151 }
2152
2153 $cssstring = '';
2154
2155 if (in_array($type, array('date', 'datetime', 'datetimegmt',))) {
2156 $cssstring = "center";
2157 } elseif (in_array($type, array('int', 'price', 'double'))) {
2158 $cssstring = "right";
2159 } elseif (in_array($type, array('boolean', 'radio', 'checkbox', 'ip', 'icon'))) {
2160 $cssstring = "center";
2161 }
2162
2163 if (!empty($this->attributes[$extrafieldsobjectkey]['csslist'][$key])) {
2164 $cssstring .= ($cssstring ? ' ' : '').$this->attributes[$extrafieldsobjectkey]['csslist'][$key];
2165 } else {
2166 if (in_array($type, array('ip'))) {
2167 $cssstring .= ($cssstring ? ' ' : '').'tdoverflowmax150';
2168 }
2169 }
2170
2171 return $cssstring;
2172 }
2173
2184 public function showSeparator($key, $object, $colspan = 2, $display_type = 'card', $mode = '')
2185 {
2186 global $conf, $langs;
2187
2188 $tagtype = 'tr';
2189 $tagtype_dyn = 'td';
2190
2191 if ($display_type == 'line') {
2192 $tagtype = 'div';
2193 $tagtype_dyn = 'span';
2194 $colspan = 0;
2195 }
2196
2197 $extrafield_param = $this->attributes[$object->table_element]['param'][$key];
2198 $extrafield_param_list = array();
2199 if (!empty($extrafield_param) && is_array($extrafield_param)) {
2200 $extrafield_param_list = array_keys($extrafield_param['options']);
2201 }
2202
2203 // Set $extrafield_collapse_display_value (do we have to collapse/expand the group after the separator)
2204 $extrafield_collapse_display_value = -1;
2205 $expand_display = false;
2206 if (is_array($extrafield_param_list) && count($extrafield_param_list) > 0) {
2207 $extrafield_collapse_display_value = intval($extrafield_param_list[0]);
2208 $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));
2209 }
2210 $disabledcookiewrite = 0;
2211 if ($mode == 'create') {
2212 // On create mode, force separator group to not be collapsible
2213 $extrafield_collapse_display_value = 1;
2214 $expand_display = true; // We force group to be shown expanded
2215 $disabledcookiewrite = 1; // We keep status of group unchanged into the cookie
2216 }
2217
2218 $out = '<'.$tagtype.' id="trextrafieldseparator'.$key.(!empty($object->id) ? '_'.$object->id : '').'" class="trextrafieldseparator trextrafieldseparator'.$key.(!empty($object->id) ? '_'.$object->id : '').'">';
2219 $out .= '<'.$tagtype_dyn.' '.(!empty($colspan) ? 'colspan="' . $colspan . '"' : '').'>';
2220 // Some js code will be injected here to manage the collapsing of extrafields
2221 // Output the picto
2222 $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>';
2223 $out .= '&nbsp;';
2224 $out .= '<strong>';
2225 $out .= $langs->trans($this->attributes[$object->table_element]['label'][$key]);
2226 $out .= '</strong>';
2227 $out .= '</'.$tagtype_dyn.'>';
2228 $out .= '</'.$tagtype.'>';
2229
2230 $collapse_group = $key.(!empty($object->id) ? '_'.$object->id : '');
2231 //$extrafields_collapse_num = $this->attributes[$object->table_element]['pos'][$key].(!empty($object->id)?'_'.$object->id:'');
2232
2233 if ($extrafield_collapse_display_value == 1 || $extrafield_collapse_display_value == 2) {
2234 // Set the collapse_display status to cookie in priority or if ignorecollapsesetup is 1, if cookie and ignorecollapsesetup not defined, use the setup.
2235 $this->expand_display[$collapse_group] = $expand_display;
2236
2237 if (!empty($conf->use_javascript_ajax)) {
2238 $out .= '<!-- Add js script to manage the collapse/uncollapse of extrafields separators '.$key.' -->'."\n";
2239 $out .= '<script nonce="'.getNonce().'" type="text/javascript">'."\n";
2240 $out .= 'jQuery(document).ready(function(){'."\n";
2241 if (empty($disabledcookiewrite)) {
2242 if ($expand_display === false) {
2243 $out .= ' console.log("Inject js for the collapsing of extrafield '.$key.' - hide");'."\n";
2244 $out .= ' jQuery(".trextrafields_collapse'.$collapse_group.'").hide();'."\n";
2245 } else {
2246 $out .= ' console.log("Inject js for collapsing of extrafield '.$key.' - keep visible and set cookie");'."\n";
2247 $out .= ' document.cookie = "DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.'=1; path='.$_SERVER["PHP_SELF"].'"'."\n";
2248 }
2249 }
2250 $out .= ' jQuery("#trextrafieldseparator'.$key.(!empty($object->id) ? '_'.$object->id : '').'").click(function(){'."\n";
2251 $out .= ' console.log("We click on collapse/uncollapse to hide/show .trextrafields_collapse'.$collapse_group.'");'."\n";
2252 $out .= ' jQuery(".trextrafields_collapse'.$collapse_group.'").toggle(100, function(){'."\n";
2253 $out .= ' if (jQuery(".trextrafields_collapse'.$collapse_group.'").is(":hidden")) {'."\n";
2254 $out .= ' jQuery("#trextrafieldseparator'.$key.(!empty($object->id) ? '_'.$object->id : '').' '.$tagtype_dyn.' span").addClass("fa-plus-square").removeClass("fa-minus-square");'."\n";
2255 $out .= ' document.cookie = "DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.'=0; path='.$_SERVER["PHP_SELF"].'"'."\n";
2256 $out .= ' } else {'."\n";
2257 $out .= ' jQuery("#trextrafieldseparator'.$key.(!empty($object->id) ? '_'.$object->id : '').' '.$tagtype_dyn.' span").addClass("fa-minus-square").removeClass("fa-plus-square");'."\n";
2258 $out .= ' document.cookie = "DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.'=1; path='.$_SERVER["PHP_SELF"].'"'."\n";
2259 $out .= ' }'."\n";
2260 $out .= ' });'."\n";
2261 $out .= ' });'."\n";
2262 $out .= '});'."\n";
2263 $out .= '</script>'."\n";
2264 }
2265 } else {
2266 $this->expand_display[$collapse_group] = 1;
2267 }
2268
2269 return $out;
2270 }
2271
2283 public function setOptionalsFromPost($extralabels, &$object, $onlykey = '', $todefaultifmissing = 0)
2284 {
2285 global $langs;
2286
2287 $nofillrequired = 0; // For error when required field left blank
2288 $error_field_required = array();
2289
2290 if (isset($this->attributes[$object->table_element]['label']) && is_array($this->attributes[$object->table_element]['label'])) {
2291 $extralabels = $this->attributes[$object->table_element]['label'];
2292 }
2293
2294 if (is_array($extralabels)) {
2295 // Get extra fields
2296 foreach ($extralabels as $key => $value) {
2297 if (!empty($onlykey) && $onlykey != '@GETPOSTISSET' && $key != $onlykey) {
2298 continue;
2299 }
2300
2301 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')))) {
2302 //when unticking boolean field, it's not set in POST
2303 continue;
2304 }
2305
2306 $key_type = $this->attributes[$object->table_element]['type'][$key];
2307 if ($key_type == 'separate') {
2308 continue;
2309 }
2310
2311 $enabled = 1;
2312 if (isset($this->attributes[$object->table_element]['enabled'][$key])) { // 'enabled' is often a condition on module enabled or not
2313 $enabled = (int) dol_eval($this->attributes[$object->table_element]['enabled'][$key], 1, 1, '2');
2314 }
2315
2316 $visibility = 1;
2317 if (isset($this->attributes[$object->table_element]['list'][$key])) { // 'list' is option for visibility
2318 $visibility = (int) dol_eval($this->attributes[$object->table_element]['list'][$key], 1, 1, '2');
2319 }
2320
2321 $perms = 1;
2322 if (isset($this->attributes[$object->table_element]['perms'][$key])) {
2323 $perms = (int) dol_eval($this->attributes[$object->table_element]['perms'][$key], 1, 1, '2');
2324 }
2325 if (empty($enabled)
2326 || (
2327 $onlykey === '@GETPOSTISSET'
2328 && in_array($this->attributes[$object->table_element]['type'][$key], array('boolean', 'checkbox', 'chkbxlst'))
2329 && in_array(abs($enabled), array(2, 5))
2330 && ! GETPOSTISSET('options_' . $key) // Update hidden checkboxes and multiselect only if they are provided
2331 )
2332 ) {
2333 continue;
2334 }
2335
2336 $visibility_abs = abs($visibility);
2337 // not modify if extra field is not in update form (0 : never, 2 or -2 : list only, 5 or - 5 : list and view only)
2338 if (empty($visibility_abs) || $visibility_abs == 2 || $visibility_abs == 5) {
2339 continue;
2340 }
2341 if (empty($perms)) {
2342 continue;
2343 }
2344
2345 if ($this->attributes[$object->table_element]['required'][$key]) { // Value is required
2346 // Check if functionally empty without using GETPOST (depending on the type of extrafield, a
2347 // technically non-empty value may be treated as empty functionally).
2348 // value can be alpha, int, array, etc...
2349 $v = $_POST["options_".$key] ?? null;
2350 $type = $this->attributes[$object->table_element]['type'][$key];
2351 if (self::isEmptyValue($v, $type)) {
2352 //print 'ccc'.$value.'-'.$this->attributes[$object->table_element]['required'][$key];
2353
2354 // 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.
2355
2356 $nofillrequired++;
2357 if (!empty($this->attributes[$object->table_element]['langfile'][$key])) {
2358 $langs->load($this->attributes[$object->table_element]['langfile'][$key]);
2359 }
2360 $error_field_required[$key] = $langs->transnoentitiesnoconv($value);
2361 }
2362 }
2363
2364 if (in_array($key_type, array('date'))) {
2365 // Clean parameters
2366 $value_key = dol_mktime(12, 0, 0, GETPOSTINT("options_".$key."month"), GETPOSTINT("options_".$key."day"), GETPOSTINT("options_".$key."year"));
2367 } elseif (in_array($key_type, array('datetime'))) {
2368 // Clean parameters
2369 $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');
2370 } elseif (in_array($key_type, array('datetimegmt'))) {
2371 // Clean parameters
2372 $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');
2373 } elseif (in_array($key_type, array('checkbox', 'chkbxlst'))) {
2374 $value_arr = GETPOST("options_".$key, 'array'); // check if an array
2375 if (!empty($value_arr)) {
2376 $value_key = implode(',', $value_arr);
2377 } else {
2378 $value_key = '';
2379 }
2380 } elseif (in_array($key_type, array('price', 'double'))) {
2381 $value_arr = GETPOST("options_".$key, 'alpha');
2382 $value_key = price2num($value_arr);
2383 } elseif (in_array($key_type, array('pricecy', 'double'))) {
2384 $value_key = price2num(GETPOST("options_".$key, 'alpha')).':'.GETPOST("options_".$key."currency_id", 'alpha');
2385 } elseif (in_array($key_type, array('html'))) {
2386 $value_key = GETPOST("options_".$key, 'restricthtml');
2387 } elseif (in_array($key_type, ['point', 'multipts', 'linestrg', 'polygon'])) {
2388 // construct point
2389 require_once DOL_DOCUMENT_ROOT.'/core/class/dolgeophp.class.php';
2390 $geojson = GETPOST("options_".$key, 'restricthtml');
2391 if ($geojson != '{}') {
2392 $dolgeophp = new DolGeoPHP($this->db);
2393 $value_key = $dolgeophp->getWkt($geojson);
2394 } else {
2395 $value_key = '';
2396 }
2397 } elseif (in_array($key_type, array('text'))) {
2398 $label_security_check = 'alphanohtml';
2399 // by default 'alphanohtml' (better security); hidden conf MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML allows basic html
2400 if (getDolGlobalString('MAIN_SECURITY_ALLOW_UNSECURED_REF_LABELS')) {
2401 $label_security_check = 'nohtml';
2402 } else {
2403 $label_security_check = !getDolGlobalString('MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML') ? 'alphanohtml' : 'restricthtml';
2404 }
2405 $value_key = GETPOST("options_".$key, $label_security_check);
2406 } else {
2407 $value_key = GETPOST("options_".$key);
2408 if (in_array($key_type, array('link')) && $value_key == '-1') {
2409 $value_key = '';
2410 }
2411 }
2412
2413 if (!empty($error_field_required[$key]) && $todefaultifmissing) {
2414 // Value is required but we have a default value and we asked to set empty value to the default value
2415 if (!empty($this->attributes[$object->table_element]['default']) && !is_null($this->attributes[$object->table_element]['default'][$key])) {
2416 $value_key = $this->attributes[$object->table_element]['default'][$key];
2417 unset($error_field_required[$key]);
2418 $nofillrequired--;
2419 }
2420 }
2421
2422 $object->array_options["options_".$key] = $value_key;
2423 }
2424
2425 if ($nofillrequired) {
2426 $langs->load('errors');
2427 $this->error = $langs->trans('ErrorFieldsRequired').' : '.implode(', ', $error_field_required);
2428 setEventMessages($this->error, null, 'errors');
2429 return -1;
2430 } else {
2431 return 1;
2432 }
2433 } else {
2434 return 0;
2435 }
2436 }
2437
2446 public function getOptionalsFromPost($extrafieldsobjectkey, $keysuffix = '', $keyprefix = '')
2447 {
2448 global $_POST;
2449
2450 if (is_string($extrafieldsobjectkey) && !empty($this->attributes[$extrafieldsobjectkey]['label']) && is_array($this->attributes[$extrafieldsobjectkey]['label'])) {
2451 $extralabels = $this->attributes[$extrafieldsobjectkey]['label'];
2452 } else {
2453 $extralabels = $extrafieldsobjectkey;
2454 }
2455
2456 if (is_array($extralabels)) {
2457 $array_options = array();
2458
2459 // Get extra fields
2460 foreach ($extralabels as $key => $value) {
2461 $key_type = '';
2462 if (is_string($extrafieldsobjectkey)) {
2463 $key_type = $this->attributes[$extrafieldsobjectkey]['type'][$key];
2464 }
2465
2466 if (in_array($key_type, array('date'))) {
2467 $dateparamname_start = $keyprefix . 'options_' . $key . $keysuffix . '_start';
2468 $dateparamname_end = $keyprefix . 'options_' . $key . $keysuffix . '_end';
2469 if (GETPOST($dateparamname_start . 'year') || GETPOST($dateparamname_end . 'year')) {
2470 $value_key = array();
2471 // values provided as a component year, month, day, etc.
2472 if (GETPOST($dateparamname_start . 'year')) {
2473 $value_key['start'] = dol_mktime(0, 0, 0, GETPOSTINT($dateparamname_start . 'month'), GETPOSTINT($dateparamname_start . 'day'), GETPOSTINT($dateparamname_start . 'year'));
2474 }
2475 if (GETPOST($dateparamname_start . 'year')) {
2476 $value_key['end'] = dol_mktime(23, 59, 59, GETPOSTINT($dateparamname_end . 'month'), GETPOSTINT($dateparamname_end . 'day'), GETPOSTINT($dateparamname_end . 'year'));
2477 }
2478 } elseif (GETPOST($keyprefix."options_".$key.$keysuffix."year")) {
2479 // Clean parameters
2480 $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"));
2481 } else {
2482 continue; // Value was not provided, we should not set it.
2483 }
2484 } elseif (in_array($key_type, array('datetime', 'datetimegmt'))) {
2485 $dateparamname_start = $keyprefix . 'options_' . $key . $keysuffix . '_start';
2486 $dateparamname_end = $keyprefix . 'options_' . $key . $keysuffix . '_end';
2487
2488 if (GETPOST($dateparamname_start . 'year') && GETPOST($dateparamname_end . 'year')) {
2489 // values provided as a date pair (start date + end date), each date being broken down as year, month, day, etc.
2490 $dateparamname_end_hour = GETPOSTINT($dateparamname_end . 'hour') != '-1' ? GETPOSTINT($dateparamname_end . 'hour') : '23';
2491 $dateparamname_end_min = GETPOSTINT($dateparamname_end . 'min') != '-1' ? GETPOSTINT($dateparamname_end . 'min') : '59';
2492 $dateparamname_end_sec = GETPOSTINT($dateparamname_end . 'sec') != '-1' ? GETPOSTINT($dateparamname_end . 'sec') : '59';
2493 if ($key_type == 'datetimegmt') {
2494 $value_key = array(
2495 'start' => dol_mktime(GETPOSTINT($dateparamname_start . 'hour'), GETPOSTINT($dateparamname_start . 'min'), GETPOSTINT($dateparamname_start . 'sec'), GETPOSTINT($dateparamname_start . 'month'), GETPOSTINT($dateparamname_start . 'day'), GETPOSTINT($dateparamname_start . 'year'), 'gmt'),
2496 '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')
2497 );
2498 } else {
2499 $value_key = array(
2500 'start' => dol_mktime(GETPOSTINT($dateparamname_start . 'hour'), GETPOSTINT($dateparamname_start . 'min'), GETPOSTINT($dateparamname_start . 'sec'), GETPOSTINT($dateparamname_start . 'month'), GETPOSTINT($dateparamname_start . 'day'), GETPOSTINT($dateparamname_start . 'year'), 'tzuserrel'),
2501 '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')
2502 );
2503 }
2504 } elseif (GETPOST($keyprefix."options_".$key.$keysuffix."year")) {
2505 // Clean parameters
2506 if ($key_type == 'datetimegmt') {
2507 $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');
2508 } else {
2509 $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');
2510 }
2511 } else {
2512 continue; // Value was not provided, we should not set it.
2513 }
2514 } elseif ($key_type == 'select') {
2515 // to detect if we are in search context
2516 if (GETPOSTISARRAY($keyprefix."options_".$key.$keysuffix)) {
2517 $value_arr = GETPOST($keyprefix."options_".$key.$keysuffix, 'array:aZ09');
2518 // Make sure we get an array even if there's only one selected
2519 $value_arr = (array) $value_arr;
2520 $value_key = implode(',', $value_arr);
2521 } else {
2522 $value_key = GETPOST($keyprefix."options_".$key.$keysuffix);
2523 }
2524 } elseif (in_array($key_type, array('checkbox', 'chkbxlst'))) {
2525 // We test on a hidden field named "..._multiselect" that is always set to 1 if param is in form so
2526 // when nothing is provided we can make a difference between noparam in the form and param was set to nothing.
2527 if (!GETPOSTISSET($keyprefix."options_".$key.$keysuffix.'_multiselect')) {
2528 continue; // Value was not provided, we should not set it.
2529 }
2530 $value_arr = GETPOST($keyprefix."options_".$key.$keysuffix);
2531 // Make sure we get an array even if there's only one checkbox
2532 $value_arr = (array) $value_arr;
2533 $value_key = implode(',', $value_arr);
2534 } elseif (in_array($key_type, array('price', 'double', 'int'))) {
2535 if (!GETPOSTISSET($keyprefix."options_".$key.$keysuffix)) {
2536 continue; // Value was not provided, we should not set it.
2537 }
2538 $value_arr = GETPOST($keyprefix."options_".$key.$keysuffix);
2539 if ($keyprefix != 'search_') { // If value is for a search, we must keep complex string like '>100 <=150'
2540 $value_key = price2num($value_arr);
2541 } else {
2542 $value_key = $value_arr;
2543 }
2544 } elseif (in_array($key_type, array('boolean'))) {
2545 // We test on a hidden field named "..._boolean" that is always set to 1 if param is in form so
2546 // when nothing is provided we can make a difference between noparam in the form and param was set to nothing.
2547 if (!GETPOSTISSET($keyprefix."options_".$key.$keysuffix."_boolean")) {
2548 $value_key = '';
2549 } else {
2550 $value_arr = GETPOST($keyprefix."options_".$key.$keysuffix);
2551 $value_key = $value_arr;
2552 }
2553 } elseif (in_array($key_type, array('html'))) {
2554 if (!GETPOSTISSET($keyprefix."options_".$key.$keysuffix)) {
2555 continue; // Value was not provided, we should not set it.
2556 }
2557 $value_key = dol_htmlcleanlastbr(GETPOST($keyprefix."options_".$key.$keysuffix, 'restricthtml'));
2558 } else {
2559 if (!GETPOSTISSET($keyprefix."options_".$key.$keysuffix)) {
2560 continue; // Value was not provided, we should not set it.
2561 }
2562 $value_key = GETPOST($keyprefix."options_".$key.$keysuffix);
2563 }
2564
2565 $array_options[$keyprefix."options_".$key] = $value_key; // No keyprefix here. keyprefix is used only for read.
2566 }
2567
2568 return $array_options;
2569 }
2570
2571 return 0;
2572 }
2573
2579 public static function getListOfTypesLabels()
2580 {
2581 global $langs;
2582
2583 $tmptype2label = ExtraFields::$type2label;
2584 $type2label = array('');
2585 foreach ($tmptype2label as $key => $val) {
2586 $type2label[$key] = $langs->transnoentitiesnoconv($val);
2587 }
2588
2589 if (!getDolGlobalString('MAIN_USE_EXTRAFIELDS_ICON')) {
2590 unset($type2label['icon']);
2591 }
2592 if (!getDolGlobalString('MAIN_USE_GEOPHP')) {
2593 unset($type2label['point']);
2594 unset($type2label['multipts']);
2595 unset($type2label['linestrg']);
2596 unset($type2label['polygon']);
2597 }
2598
2599 return $type2label;
2600 }
2601
2609 public static function isEmptyValue($v, string $type)
2610 {
2611 if ($v === null || $v === '') {
2612 return true;
2613 }
2614 if (is_array($v) || $type == 'select') {
2615 return empty($v);
2616 }
2617 if ($type == 'link') {
2618 return ($v == '-1');
2619 }
2620 if ($type == 'sellist') {
2621 return ($v == '0');
2622 }
2623 return (empty($v) && $v != '0');
2624 }
2625}
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...