dolibarr 24.0.0-beta
html.formwebportal.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2023-2024 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2023-2024 Lionel Vessiller <lvessiller@easya.solutions>
4 * Copyright (C) 2023-2024 Patrice Andreani <pandreani@easya.solutions>
5 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
6 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
7 * Copyright (C) 2026 Charlene Benke <charlene@patas-monkey.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
23
30require_once DOL_DOCUMENT_ROOT . '/core/class/html.form.class.php';
31
36class FormWebPortal extends Form
37{
41 public $db;
42
46 public $infofiles; // Used to return information by function getDocumentsLink
47
48
54 public function __construct($db)
55 {
56 $this->db = $db;
57 }
58
70 public function inputDate($name, $value = '', $placeholder = '', $id = '', $morecss = '', $moreparam = '')
71 {
72 $out = '';
73
74 // Disabled: Use of native browser date input field as it is not compliant with multilanguagedate format,
75 // nor with timezone management.
76 /*
77 $out .= '<input';
78 if ($placeholder != '' && $value == '') {
79 // to show a placeholder on date input
80 $out .= ' type="text" placeholder="' . $placeholder . '" onfocus="(this.type=\'date\')"';
81 } else {
82 $out .= ' type="date"';
83 }
84 $out .= ($morecss ? ' class="' . $morecss . '"' : '');
85 if ($id != '') {
86 $out .= ' id="' . $id . '"';
87 }
88 $out .= ' name="' . $name . '"';
89 $out .= ' value="' . $value . '"';
90 $out .= ($moreparam ? ' ' . $moreparam : '');
91
92 $out .= '>';
93 */
94
95 $out = $this->selectDate($value === '' ? -1 : $value, $name, 0, 0, 0, "", 1, 0, 0, '', '', '', '', 1, '', $placeholder, 'auto', DOL_URL_ROOT . "/theme/common/object_calendarday.png");
96
97 return $out;
98 }
99
122 public static function selectarray($htmlname, $array, $id = '', $show_empty = 0, $key_in_label = 0, $value_as_key = 0, $moreparam = '', $translate = 0, $maxlen = 0, $disabled = 0, $sort = '', $morecss = 'minwidth75', $addjscombo = 1, $moreparamonempty = '', $disablebademail = 0, $nohtmlescape = 0)
123 {
124 global $langs;
125
126 if ($value_as_key) {
127 $array = array_combine($array, $array);
128 }
129
130 $out = '';
131
132 $idname = str_replace(array('[', ']'), array('', ''), $htmlname);
133 $out .= '<select id="' . preg_replace('/^\./', '', $idname) . '"' . ($disabled ? ' disabled="disabled"' : '') . ' class="' . ($morecss ? ' ' . $morecss : '') . '"';
134 $out .= ' name="' . preg_replace('/^\./', '', $htmlname) . '"' . ($moreparam ? ' ' . $moreparam : '');
135 $out .= '>' . "\n";
136
137 if ($show_empty) {
138 $textforempty = ' ';
139 if (!is_numeric($show_empty)) {
140 $textforempty = $show_empty;
141 }
142 $out .= '<option value="' . ($show_empty < 0 ? $show_empty : -1) . '"' . ($id == $show_empty ? ' selected' : '') . '>' . $textforempty . '</option>' . "\n";
143 }
144
145 if (is_array($array)) {
146 // Translate
147 if ($translate) {
148 foreach ($array as $key => $value) {
149 if (!is_array($value)) {
150 $array[$key] = $langs->trans($value);
151 } else {
152 $array[$key]['label'] = $langs->trans($value['label']);
153 }
154 }
155 }
156
157 // Sort
158 if ($sort == 'ASC') {
159 asort($array);
160 } elseif ($sort == 'DESC') {
161 arsort($array);
162 }
163
164 foreach ($array as $key => $tmpvalue) {
165 if (is_array($tmpvalue)) {
166 $value = $tmpvalue['label'];
167 $disabled = empty($tmpvalue['disabled']) ? '' : ' disabled';
168 } else {
169 $value = $tmpvalue;
170 $disabled = '';
171 }
172
173 if ($key_in_label) {
174 $selectOptionValue = dol_escape_htmltag($key . ' - ' . ($maxlen ? dol_trunc($value, $maxlen) : $value));
175 } else {
176 $selectOptionValue = dol_escape_htmltag($maxlen ? dol_trunc($value, $maxlen) : $value);
177 if ($value == '' || $value == '-') {
178 $selectOptionValue = '&nbsp;';
179 }
180 }
181
182 $out .= '<option value="' . $key . '"';
183 $out .= $disabled;
184 $out .= is_array($tmpvalue) && !empty($tmpvalue['parent']) ? ' parent="' . dolPrintHTMLForAttribute($tmpvalue['parent']) . '"' : '';
185 if (is_array($id)) {
186 if (in_array($key, $id) && !$disabled) {
187 $out .= ' selected'; // To preselect a value
188 }
189 } else {
190 $id = (string) $id; // if $id = 0, then $id = '0'
191 if ($id != '' && ($id == $key || ($id == 'ifone' && count($array) == 1)) && !$disabled) {
192 $out .= ' selected'; // To preselect a value
193 }
194 }
195 if (is_array($tmpvalue)) {
196 foreach ($tmpvalue as $keyforvalue => $valueforvalue) {
197 if (preg_match('/^data-/', $keyforvalue)) {
198 $out .= ' ' . $keyforvalue . '="' . dol_escape_htmltag($valueforvalue) . '"';
199 }
200 }
201 }
202 $out .= '>';
203 $out .= $selectOptionValue;
204 $out .= "</option>\n";
205 }
206 }
207
208 $out .= "</select>";
209
210 return $out;
211 }
212
226 public function getDocumentsLink($modulepart, $modulesubdir, $filedir, $filter = '', $morecss = '', $allfiles = 0)
227 {
228 include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
229
230 $out = '';
231
233 if (!$context) {
234 return '';
235 }
236
237 $this->infofiles = array('nboffiles' => 0, 'extensions' => array(), 'files' => array());
238
239 $entity = 1; // Without multicompany
240
241 // Get object entity
242 if (isModEnabled('multicompany')) {
243 $regs = array();
244 preg_match('/\/([0-9]+)\/[^\/]+\/' . preg_quote($modulesubdir, '/') . '$/', $filedir, $regs);
245 $entity = ((!empty($regs[1]) && $regs[1] > 1) ? $regs[1] : 1); // If entity id not found in $filedir this is entity 1 by default
246 }
247
248 // Get list of files starting with name of ref (Note: files with '^ref\.extension' are generated files, files with '^ref-...' are uploaded files)
249 if ($allfiles || getDolGlobalString('MAIN_SHOW_ALL_FILES_ON_DOCUMENT_TOOLTIP')) {
250 $filterforfilesearch = '^' . preg_quote(basename($modulesubdir), '/');
251 } else {
252 $filterforfilesearch = '^' . preg_quote(basename($modulesubdir), '/') . '\.';
253 }
254 $file_list = dol_dir_list($filedir, 'files', 0, $filterforfilesearch, '\.meta$|\.png$'); // We also discard .meta and .png preview
255
256 //var_dump($file_list);
257 // For ajax treatment
258 $out .= '<!-- html.formwebportal::getDocumentsLink -->' . "\n";
259 if (!empty($file_list)) {
260 $tmpout = '';
261
262 // Loop on each file found
263 $found = 0;
264 $i = 0;
265 foreach ($file_list as $file) {
266 $i++;
267 if ($filter && !preg_match('/' . $filter . '/i', $file["name"])) {
268 continue; // Discard this. It does not match provided filter.
269 }
270
271 $found++;
272 // Define relative path for download link (depends on module)
273 $relativepath = $file["name"]; // Cas general
274 if ($modulesubdir) {
275 $relativepath = $modulesubdir . "/" . $file["name"]; // Cas propal, facture...
276 }
277 // Autre cas
278 if ($modulepart == 'donation') {
279 $relativepath = get_exdir($modulesubdir, 2, 0, 0, null, 'donation') . $file["name"];
280 }
281 if ($modulepart == 'export') {
282 $relativepath = $file["name"];
283 }
284
285 $this->infofiles['nboffiles']++;
286 $this->infofiles['files'][] = $file['fullname'];
287 $ext = pathinfo($file["name"], PATHINFO_EXTENSION);
288 if (empty($this->infofiles['extensions'][$ext])) {
289 $this->infofiles['extensions'][$ext] = 1;
290 } else {
291 // @phan-suppress-next-line PhanTypeInvalidDimOffset
292 $this->infofiles['extensions'][$ext]++;
293 }
294
295 // Download
296 $url = $context->getControllerUrl('document') . '&modulepart=' . $modulepart . '&entity=' . $entity . '&file=' . urlencode($relativepath) . '&soc_id=' . $context->logged_thirdparty->id;
297
298 $tmpout .= '<a href="' . $url . '" class="btn-download-link ' . $morecss . '" role="downloadlink"';
299 $mime = dol_mimetype($relativepath, '', 0);
300 if (preg_match('/text/', $mime)) {
301 $tmpout .= ' target="_blank" rel="noopener noreferrer"';
302 }
303 $tmpout .= '>';
304 $tmpout .= img_mime($relativepath, $file["name"]);
305 $tmpout .= strtoupper($ext);
306 $tmpout .= '</a>';
307 }
308
309 if ($found) {
310 $out .= $tmpout;
311 }
312 }
313
314 return $out;
315 }
316
327 public function getSignatureLink($modulepart, $object, $morecss = '')
328 {
329 global $langs;
330 require_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php';
331 $out = '<!-- html.formwebportal::getSignatureLink -->' . "\n";
332 $url = getOnlineSignatureUrl(0, $modulepart, $object->ref, 1, $object);
333 if (!empty($url)) {
334 $out .= '<a target="_blank" rel="noopener noreferrer" href="' . $url . '"' . ($morecss ? ' class="' . $morecss . '"' : '') . ' role="signaturelink">';
335 $out .= '<i class="fa fa-file-signature"></i>';
336 $out .= $langs->trans("Sign");
337 $out .= '</a>';
338 }
339 return $out;
340 }
341
362 public function selectForForms($objectdesc, $htmlname, $preselectedvalue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $disabled = 0, $selected_input_value = '', $objectfield = '')
363 {
364 global $conf;
365
366 $objecttmp = null;
367
368 // Example of value for $objectdec:
369 // Bom:bom/class/bom.class.php:0:t.status=1
370 // Bom:bom/class/bom.class.php:0:t.status=1:ref
371 // Bom:bom/class/bom.class.php:0:(t.status:=:1):ref
372 $InfoFieldList = explode(":", $objectdesc, 4);
373 $vartmp = (empty($InfoFieldList[3]) ? '' : $InfoFieldList[3]);
374 $reg = array();
375 if (preg_match('/^.*:(\w*)$/', $vartmp, $reg)) {
376 $InfoFieldList[4] = $reg[1]; // take the sort field
377 }
378 $InfoFieldList[3] = preg_replace('/:\w*$/', '', $vartmp); // take the filter field
379
380 $classname = $InfoFieldList[0];
381 $classpath = $InfoFieldList[1];
382 $filter = empty($InfoFieldList[3]) ? '' : $InfoFieldList[3];
383 $sortfield = empty($InfoFieldList[4]) ? '' : $InfoFieldList[4];
384 if (!empty($classpath)) {
385 dol_include_once($classpath);
386
387 if ($classname && class_exists($classname)) {
388 $objecttmp = new $classname($this->db);
389
390 // Make some replacement
391 $sharedentities = getEntity(strtolower($classname));
392 $filter = str_replace(
393 array('__ENTITY__', '__SHARED_ENTITIES__'),
394 array($conf->entity, $sharedentities),
395 $filter
396 );
397 }
398 }
399 if (!is_object($objecttmp)) {
400 dol_syslog('Error bad setup of type for field ' . implode(',', $InfoFieldList), LOG_WARNING);
401 return 'Error bad setup of type for field ' . implode(',', $InfoFieldList);
402 }
403
404 dol_syslog(__METHOD__ . ' filter=' . $filter, LOG_DEBUG);
405 $out = '';
406 // Immediate load of table record.
407 $out .= $this->selectForFormsList($objecttmp, $htmlname, $preselectedvalue, $showempty, $searchkey, $placeholder, $morecss, $moreparams, $forcecombo, 0, $disabled, $sortfield, $filter);
408
409 return $out;
410 }
411
426 public function showInputFieldForObject($object, $val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '')
427 {
428 // TODO Replace code with
429 //return $object->showInputField($val, $key, $value, '', '', '', 0);
430
431 global $conf, $langs;
432
433 $out = '';
434 $param = array();
435 $reg = array();
436 $size = !empty($val['size']) ? $val['size'] : 0;
437 // see common object class
438 if (preg_match('/^(integer|link):(.*):(.*):(.*):(.*)/i', $val['type'], $reg)) {
439 $param['options'] = array($reg[2] . ':' . $reg[3] . ':' . $reg[4] . ':' . $reg[5] => 'N');
440 $type = 'link';
441 } elseif (preg_match('/^(integer|link):(.*):(.*):(.*)/i', $val['type'], $reg)) {
442 $param['options'] = array($reg[2] . ':' . $reg[3] . ':' . $reg[4] => 'N');
443 $type = 'link';
444 } elseif (preg_match('/^(integer|link):(.*):(.*)/i', $val['type'], $reg)) {
445 $param['options'] = array($reg[2] . ':' . $reg[3] => 'N');
446 $type = 'link';
447 } elseif (preg_match('/^(sellist):(.*):(.*):(.*):(.*)/i', $val['type'], $reg)) {
448 $param['options'] = array($reg[2] . ':' . $reg[3] . ':' . $reg[4] . ':' . $reg[5] => 'N');
449 $type = 'sellist';
450 } elseif (preg_match('/^(sellist):(.*):(.*):(.*)/i', $val['type'], $reg)) {
451 $param['options'] = array($reg[2] . ':' . $reg[3] . ':' . $reg[4] => 'N');
452 $type = 'sellist';
453 } elseif (preg_match('/^(sellist):(.*):(.*)/i', $val['type'], $reg)) {
454 $param['options'] = array($reg[2] . ':' . $reg[3] => 'N');
455 $type = 'sellist';
456 } elseif (preg_match('/^varchar\‍((\d+)\‍)/', $val['type'], $reg)) {
457 $param['options'] = array();
458 $type = 'text';
459 $size = $reg[1];
460 } elseif (preg_match('/^varchar/', $val['type'])) {
461 $param['options'] = array();
462 $type = 'text';
463 } elseif (preg_match('/^double(\‍([0-9],[0-9]\‍)){0,1}/', $val['type'])) {
464 $param['options'] = array();
465 $type = 'double';
466 } else {
467 $param['options'] = array();
468 $type = $val['type'];
469 }
470
471 // Special case that force options and type ($type can be integer, varchar, ...)
472 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
473 $param['options'] = $val['arrayofkeyval'];
474 $type = $val['type'] == 'checkbox' ? 'checkbox' : 'select';
475 }
476
477 //$label = $val['label'];
478 $default = (!empty($val['default']) ? $val['default'] : '');
479 $computed = (!empty($val['computed']) ? $val['computed'] : '');
480 //$unique = (!empty($val['unique']) ? $val['unique'] : 0);
481 $required = (!empty($val['required']) ? $val['required'] : 0);
482 $notNull = (!empty($val['notnull']) ? $val['notnull'] : 0);
483
484 //$langfile = (!empty($val['langfile']) ? $val['langfile'] : '');
485 //$list = (!empty($val['list']) ? $val[$key]['list'] : 0);
486 $hidden = (in_array(abs($val['visible']), array(0, 2)) ? 1 : 0);
487
488 //$objectid = $this->id;
489
490 if ($computed) {
491 if (!preg_match('/^search_/', $keyprefix)) {
492 return '<span>' . $langs->trans("AutomaticallyCalculated") . '</span>';
493 } else {
494 return '';
495 }
496 }
497
498 // Set value of $morecss. For this, we use in priority showsize from parameters, then $val['css'] then autodefine
499 if (empty($morecss) && !empty($val['css'])) {
500 $morecss = $val['css'];
501 }
502
503 $htmlName = $keyprefix . $key . $keysuffix;
504 $htmlId = $htmlName;
505 //$moreparam .= (!empty($required) ? ' required' : '');
506 switch ($type) {
507 case 'date':
508 case 'datetime':
509 // separate value YYYY-MM-DD HH:ii:ss to date and time
510 $valueDate = '';
511 $valueTime = '';
512 $dateArr = explode(' ', $value);
513 if (count($dateArr) > 0) {
514 $valueDate = $dateArr[0];
515 if (isset($dateArr[1])) {
516 $valueTime = $dateArr[1];
517 }
518 }
519 $out = $this->inputDate($htmlName, $valueDate, '', $htmlId, $morecss, $moreparam);
520
521 if ($type == 'datetime') {
522 //$moreparam .= ' step="1"'; to show seconds
523 $out .= ' ' . $this->inputType('time', $htmlName.'_time', $valueTime, $htmlId, $morecss, $moreparam);
524 }
525 break;
526
527 case 'integer':
528 $out = $this->inputType('number', $htmlName, dol_escape_htmltag($value), $htmlId, $morecss, $moreparam);
529 break;
530
531 case 'text':
532 case 'html':
533 $moreparam .= ($size > 0 ? ' maxlength="' . $size . '"' : '');
534 $out = $this->inputType('text', $htmlName, dol_escape_htmltag($value), $htmlId, $morecss, $moreparam);
535 break;
536
537 case 'email':
538 $out = $this->inputType('email', $htmlName, dol_escape_htmltag($value), $htmlId, $morecss, $moreparam);
539 break;
540
541 case 'tel':
542 $out = $this->inputType('tel', $htmlName, dol_escape_htmltag($value), $htmlId, $morecss, $moreparam);
543 break;
544
545 case 'url':
546 $out = $this->inputType('url', $htmlName, dol_escape_htmltag($value), $htmlId, $morecss, $moreparam);
547 break;
548
549 case 'price':
550 if (!empty($value)) {
551 $value = price($value); // $value in memory is a php numeric, we format it into user number format.
552 }
553 $addInputLabel = ' ' . $langs->getCurrencySymbol();
554 $out = $this->inputType('text', $htmlName, $value, $htmlId, $morecss, $moreparam, '', $addInputLabel);
555 break;
556
557 case 'double':
558 if (!empty($value)) {
559 $value = price($value); // $value in memory is a php numeric, we format it into user number format.
560 }
561 $out = $this->inputType('text', $htmlName, $value, $htmlId, $morecss, $moreparam);
562 break;
563
564 case 'password':
565 $out = $this->inputType('password', $htmlName, $value, $htmlId, $morecss, $moreparam);
566 break;
567
568 case 'radio':
569 foreach ($param['options'] as $keyopt => $valopt) {
570 $htmlId = $htmlName . '_' . $keyopt;
571 $htmlMoreParam = $moreparam . ($value == $keyopt ? ' checked' : '');
572 $out .= $this->inputType('radio', $htmlName, $keyopt, $htmlId, $morecss, $htmlMoreParam, $valopt) . '<br>';
573 }
574 break;
575
576 case 'select':
577 $out = '<select class="' . $morecss . '" name="' . $htmlName . '" id="' . $htmlId . '"' . ($moreparam ? ' ' . $moreparam : '') . ' >';
578 if ($default == '' || $notNull != 1) {
579 $out .= '<option value="0">&nbsp;</option>';
580 }
581 foreach ($param['options'] as $keyb => $valb) {
582 if ($keyb == '') {
583 continue;
584 }
585 if (strpos($valb, "|") !== false) {
586 list($valb, $parent) = explode('|', $valb);
587 }
588 $out .= '<option value="' . $keyb . '"';
589 $out .= (((string) $value == $keyb) ? ' selected' : '');
590 $out .= (!empty($parent) ? ' parent="' . $parent . '"' : '');
591 $out .= '>' . $valb . '</option>';
592 }
593 $out .= '</select>';
594 break;
595 case 'sellist':
596 $out = '<select class="' . $morecss . '" name="' . $htmlName . '" id="' . $htmlId . '"' . ($moreparam ? ' ' . $moreparam : '') . '>';
597
598 $param_list = array_keys($param['options']);
599 $InfoFieldList = explode(":", $param_list[0]);
600 $parentName = '';
601 $parentField = '';
602 // 0 : tableName
603 // 1 : label field name
604 // 2 : key fields name (if differ of rowid)
605 // 3 : key field parent (for dependent lists)
606 // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
607 // 5 : id category type
608 // 6 : ids categories list separated by comma for category root
609 $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2] . ' as rowid');
610
611 if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) {
612 if (strpos($InfoFieldList[4], 'extra.') !== false) {
613 $keyList = 'main.' . $InfoFieldList[2] . ' as rowid';
614 } else {
615 $keyList = $InfoFieldList[2] . ' as rowid';
616 }
617 }
618 if (count($InfoFieldList) > 3 && !empty($InfoFieldList[3])) {
619 list($parentName, $parentField) = explode('|', $InfoFieldList[3]);
620 if (!empty($InfoFieldList[4]) && strpos($InfoFieldList[4], 'extra.') !== false) {
621 $keyList .= ', main.'.$parentField;
622 } else {
623 $keyList .= ', '.$parentField;
624 }
625 }
626
627 $filter_categorie = false;
628 if (count($InfoFieldList) > 5) {
629 if ($InfoFieldList[0] == 'categorie') {
630 $filter_categorie = true;
631 }
632 }
633
634 if (!$filter_categorie) {
635 $fields_label = isset($InfoFieldList[1]) ? explode('|', $InfoFieldList[1]) : array();
636 if (!empty($fields_label)) {
637 $keyList .= ', ';
638 $keyList .= implode(', ', $fields_label);
639 }
640
641 $sqlwhere = '';
642 $sql = "SELECT " . $this->db->sanitize($keyList, 0, 0, 1);
643 $sql .= " FROM " . $this->db->prefix() . $this->db->sanitize($InfoFieldList[0]);
644 if (!empty($InfoFieldList[4])) {
645 // can use SELECT request
646 if (strpos($InfoFieldList[4], '$SEL$') !== false) {
647 $InfoFieldList[4] = str_replace('$SEL$', 'SELECT', $InfoFieldList[4]);
648 }
649
650 // current object id can be use into filter
651 $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]);
652
653 //We have to join on extrafield table
654 if (strpos($InfoFieldList[4], 'extra') !== false) {
655 $sql .= " as main, " . $this->db->prefix() . $this->db->sanitize($InfoFieldList[0]) . "_extrafields as extra";
656 $sqlwhere .= " WHERE extra.fk_object=main." . $this->db->sanitize($InfoFieldList[2]) . " AND " . $InfoFieldList[4];
657 } else {
658 $sqlwhere .= " WHERE " . $InfoFieldList[4];
659 }
660 } else {
661 $sqlwhere .= ' WHERE 1=1';
662 }
663 // Some tables may have field, some other not. For the moment we disable it.
664 if (in_array($InfoFieldList[0], array('tablewithentity'))) {
665 $sqlwhere .= " AND entity = " . ((int) $conf->entity);
666 }
667 $sql .= $sqlwhere;
668 //print $sql;
669
670 $sql .= ' ORDER BY ' . implode(', ', $fields_label);
671
672 dol_syslog(get_class($this) . '::showInputField type=sellist', LOG_DEBUG);
673 $resql = $this->db->query($sql);
674 if ($resql) {
675 $out .= '<option value="0">&nbsp;</option>';
676 $num = $this->db->num_rows($resql);
677 $i = 0;
678 while ($i < $num) {
679 $labeltoshow = '';
680 $obj = $this->db->fetch_object($resql);
681
682 // Several field into label (eq table:code|libelle:rowid)
683 $notrans = false;
684 $fields_label = explode('|', $InfoFieldList[1]);
685 if (count($fields_label) > 1) {
686 $notrans = true;
687 foreach ($fields_label as $field_toshow) {
688 $labeltoshow .= $obj->$field_toshow . ' ';
689 }
690 } else {
691 $labeltoshow = $obj->{$InfoFieldList[1]};
692 }
693 $labeltoshow = dol_trunc($labeltoshow, 45);
694
695 if ($value == $obj->rowid) {
696 foreach ($fields_label as $field_toshow) {
697 $translabel = $langs->trans($obj->$field_toshow);
698 if ($translabel != $obj->$field_toshow) {
699 $labeltoshow = dol_trunc($translabel) . ' ';
700 } else {
701 $labeltoshow = dol_trunc($obj->$field_toshow) . ' ';
702 }
703 }
704 $out .= '<option value="' . $obj->rowid . '" selected>' . $labeltoshow . '</option>';
705 } else {
706 if (!$notrans) {
707 $translabel = $langs->trans($obj->{$InfoFieldList[1]});
708 if ($translabel != $obj->{$InfoFieldList[1]}) {
709 $labeltoshow = dol_trunc($translabel, 18);
710 } else {
711 $labeltoshow = dol_trunc($obj->{$InfoFieldList[1]});
712 }
713 }
714 if (empty($labeltoshow)) {
715 $labeltoshow = '(not defined)';
716 }
717 if ($value == $obj->rowid) {
718 $out .= '<option value="' . $obj->rowid . '" selected>' . $labeltoshow . '</option>';
719 }
720
721 if (!empty($InfoFieldList[3]) && $parentField) {
722 $parent = $parentName . ':' . $obj->{$parentField};
723 $isDependList = 1;
724 }
725
726 $out .= '<option value="' . $obj->rowid . '"';
727 $out .= ($value == $obj->rowid ? ' selected' : '');
728 $out .= (!empty($parent) ? ' parent="' . $parent . '"' : '');
729 $out .= '>' . $labeltoshow . '</option>';
730 }
731
732 $i++;
733 }
734 $this->db->free($resql);
735 } else {
736 $out .= 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.<br>';
737 }
738 } else {
739 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
740 $categorytype = $InfoFieldList[5];
741 if (is_numeric($categorytype)) { // deprecated: must use the category code instead of id. For backward compatibility.
742 $tmpcategory = new Categorie($this->db);
743 $MAP_ID_TO_CODE = array_flip($tmpcategory->MAP_ID);
744 $categorytype = $MAP_ID_TO_CODE[(int) $categorytype];
745 }
746
747 $data = $this->select_all_categories($categorytype, '', 'parent', 64, $InfoFieldList[6], 1, 1);
748 $out .= '<option value="0">&nbsp;</option>';
749 foreach ($data as $data_key => $data_value) {
750 $out .= '<option value="' . $data_key . '"';
751 $out .= ($value == $data_key ? ' selected' : '');
752 $out .= '>' . $data_value . '</option>';
753 }
754 }
755 $out .= '</select>';
756 break;
757
758 case 'link':
759 $param_list = array_keys($param['options']); // $param_list='ObjectName:classPath[:AddCreateButtonOrNot[:Filter[:Sortfield]]]'
760 $showempty = (($required && $default != '') ? '0' : '1');
761
762 $out = $this->selectForForms($param_list[0], $htmlName, (int) $value, $showempty, '', '', $morecss, $moreparam, 0, empty($val['disabled']) ? 0 : 1);
763
764 break;
765
766 default:
767 if (!empty($hidden)) {
768 $out = $this->inputType('hidden', $htmlName, $value, $htmlId);
769 }
770 break;
771 }
772
773 return $out;
774 }
775
789 public function showOutputFieldForObject($object, $val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '')
790 {
791 // TODO Replace code with
792 //return $object->showOutputField($val, $key, $value, '', '', '', 0);
793 // We must just implement different case like output a ref that must not include the link into backoffice
794
795 global $conf, $langs;
796
797 $label = empty($val['label']) ? '' : $val['label'];
798 $type = empty($val['type']) ? '' : $val['type'];
799 $css = empty($val['css']) ? '' : $val['css'];
800 $picto = empty($val['picto']) ? '' : $val['picto'];
801 $reg = array();
802
803 // Convert var to be able to share same code than showOutputField of extrafields
804 if (preg_match('/varchar\‍((\d+)\‍)/', $type, $reg)) {
805 $type = 'varchar'; // convert varchar(xx) int varchar
806 $css = $reg[1];
807 } elseif (preg_match('/varchar/', $type)) {
808 $type = 'varchar'; // convert varchar(xx) int varchar
809 }
810 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
811 $type = $val['type'] == 'checkbox' ? 'checkbox' : 'select';
812 }
813 if (preg_match('/^integer:(.*):(.*)/i', $val['type'], $reg)) {
814 $type = 'link';
815 }
816
817 $default = empty($val['default']) ? '' : $val['default'];
818 $computed = empty($val['computed']) ? '' : $val['computed'];
819 $unique = empty($val['unique']) ? '' : $val['unique'];
820 $required = empty($val['required']) ? '' : $val['required'];
821 $param = array();
822 $param['options'] = array();
823
824 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
825 $param['options'] = $val['arrayofkeyval'];
826 }
827 if (preg_match('/^integer:(.*):(.*)/i', $val['type'], $reg)) {
828 $type = 'link';
829 $stringforoptions = $reg[1] . ':' . $reg[2];
830 if ($reg[1] == 'User') {
831 $stringforoptions .= ':-1';
832 }
833 $param['options'] = array($stringforoptions => $stringforoptions);
834 } elseif (preg_match('/^sellist:(.*):(.*):(.*):(.*)/i', $val['type'], $reg)) {
835 $param['options'] = array($reg[1] . ':' . $reg[2] . ':' . $reg[3] . ':' . $reg[4] => 'N');
836 $type = 'sellist';
837 } elseif (preg_match('/^sellist:(.*):(.*):(.*)/i', $val['type'], $reg)) {
838 $param['options'] = array($reg[1] . ':' . $reg[2] . ':' . $reg[3] => 'N');
839 $type = 'sellist';
840 } elseif (preg_match('/^sellist:(.*):(.*)/i', $val['type'], $reg)) {
841 $param['options'] = array($reg[1] . ':' . $reg[2] => 'N');
842 $type = 'sellist';
843 } elseif (preg_match('/^chkbxlst:(.*)/i', $val['type'], $reg)) {
844 $param['options'] = array($reg[1] => 'N');
845 $type = 'chkbxlst';
846 }
847
848 $langfile = empty($val['langfile']) ? '' : $val['langfile'];
849 $list = (empty($val['list']) ? '' : $val['list']);
850 $help = (empty($val['help']) ? '' : $val['help']);
851 $hidden = (($val['visible'] == 0) ? 1 : 0); // If zero, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller)
852
853 if ($hidden) {
854 return '';
855 }
856
857 // If field is a computed field, value must become result of compute
858 if ($computed) {
859 // Make the eval of compute string
860 //var_dump($computed);
861 $value = (string) dol_eval((string) $computed, 1, 0, '2');
862 }
863
864 // Format output value differently according to properties of field
865 //
866 // First the cases that do not use $value from the arguments:
867 //
868 if (in_array($key, array('rowid', 'ref'))) {
869 if (property_exists($object, 'ref')) {
870 $value = (string) $object->ref;
871 } elseif (property_exists($object, 'id')) {
872 $value = $object->id;
873 } else {
874 $value = '';
875 }
876 } elseif ($key == 'status' && method_exists($object, 'getLibStatut')) {
877 $value = $object->getLibStatut(3);
878 //
879 // Then the cases where $value is an array
880 //
881 } elseif (is_array($value)) {
882 // Handle array early to get type identification solve for static
883 // analysis
884 if ($type == 'array') {
885 $value = implode('<br>', $value);
886 } else {
887 dol_syslog(__METHOD__."Unexpected type=".$type." for array value=".((string) json_encode($value)), LOG_ERR);
888 }
889 //
890 // Then the cases where $value is not an array (hence string)
891 //
892 } elseif ($type == 'date') {
893 if (!empty($value)) {
894 $value = dol_print_date($value, 'day'); // We suppose dates without time are always gmt (storage of course + output)
895 } else {
896 $value = '';
897 }
898 } elseif ($type == 'datetime' || $type == 'timestamp') {
899 if (!empty($value)) {
900 $value = dol_print_date($value, 'dayhour', 'tzuserrel');
901 } else {
902 $value = '';
903 }
904 } elseif ($type == 'duration') {
905 include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
906 if (!is_null($value) && $value !== '') {
907 $value = convertSecondToTime((int) $value, 'allhourmin');
908 } else {
909 // Resulting type must be string
910 $value = '';
911 }
912 } elseif ($type == 'double' || $type == 'real') {
913 if (!is_null($value) && $value !== '') {
914 $value = price($value);
915 } else {
916 // Resulting type must be string
917 $value = '';
918 }
919 } elseif ($type == 'boolean') {
920 $checked = '';
921 if (!empty($value)) {
922 $checked = ' checked ';
923 }
924 $value = '<input type="checkbox" ' . $checked . ' ' . ($moreparam ? $moreparam : '') . ' readonly disabled>';
925 } elseif ($type == 'mail' || $type == 'email') {
926 $value = dol_print_email($value, 0, 0, 0, 64, 1, 1);
927 } elseif ($type == 'url') {
928 $value = dol_print_url($value, '_blank', 32, 1);
929 } elseif ($type == 'phone') {
930 $value = dol_print_phone($value, '', 0, 0, '', '&nbsp;', 'phone');
931 } elseif ($type == 'ip') {
932 $value = dol_print_ip($value, 0);
933 } elseif ($type == 'price') {
934 if (!is_null($value) && $value !== '') {
935 $value = price($value, 0, $langs, 0, 0, -1, getDolCurrency());
936 } else {
937 // Resulting type must be string
938 $value = '';
939 }
940 } elseif ($type == 'select') {
941 $value = isset($param['options'][$value]) ? $param['options'][$value] : '';
942 } elseif ($type == 'sellist') {
943 $param_list = array_keys($param['options']);
944 $InfoFieldList = explode(":", $param_list[0]);
945
946 $selectkey = "rowid";
947 $keyList = 'rowid';
948
949 if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) {
950 $selectkey = $InfoFieldList[2];
951 $keyList = $InfoFieldList[2] . ' as rowid';
952 }
953
954 $fields_label = explode('|', $InfoFieldList[1]);
955 if (is_array($fields_label)) {
956 $keyList .= ', ';
957 $keyList .= implode(', ', $fields_label);
958 }
959
960 $filter_categorie = false;
961 if (count($InfoFieldList) > 5) {
962 if ($InfoFieldList[0] == 'categorie') {
963 $filter_categorie = true;
964 }
965 }
966
967 $sql = "SELECT " . $this->db->sanitize($keyList);
968 $sql .= ' FROM ' . $this->db->prefix() . $InfoFieldList[0];
969 if (strpos($InfoFieldList[4], 'extra') !== false) {
970 $sql .= ' as main';
971 }
972 if ($selectkey == 'rowid' && empty($value)) {
973 $sql .= " WHERE " . $this->db->sanitize($selectkey) . " = 0";
974 } elseif ($selectkey == 'rowid') {
975 $sql .= " WHERE " . $this->db->sanitize($selectkey) . " = " . ((int) $value);
976 } else {
977 $sql .= " WHERE " . $this->db->sanitize($selectkey) . " = '" . $this->db->escape($value) . "'";
978 }
979
980 dol_syslog(__METHOD__ . ' type=sellist', LOG_DEBUG);
981 $resql = $this->db->query($sql);
982 if ($resql) {
983 if (!$filter_categorie) {
984 $value = ''; // value was used, so now we reset it to use it to build final output
985 $numrows = $this->db->num_rows($resql);
986 if ($numrows) {
987 $obj = $this->db->fetch_object($resql);
988
989 // Several field into label (eq table:code|libelle:rowid)
990 $fields_label = explode('|', $InfoFieldList[1]);
991
992 if (is_array($fields_label) && count($fields_label) > 1) {
993 foreach ($fields_label as $field_toshow) {
994 $translabel = '';
995 if (!empty($obj->$field_toshow)) {
996 $translabel = $langs->trans($obj->$field_toshow);
997 }
998 if ($translabel != $field_toshow) {
999 $value .= dol_trunc($translabel, 18) . ' ';
1000 } else {
1001 $value .= $obj->$field_toshow . ' ';
1002 }
1003 }
1004 } else {
1005 $translabel = '';
1006 if (!empty($obj->{$InfoFieldList[1]})) {
1007 $translabel = $langs->trans($obj->{$InfoFieldList[1]});
1008 }
1009 if ($translabel != $obj->{$InfoFieldList[1]}) {
1010 $value = dol_trunc($translabel, 18);
1011 } else {
1012 $value = $obj->{$InfoFieldList[1]};
1013 }
1014 }
1015 }
1016 } else {
1017 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1018
1019 $toprint = array();
1020 $obj = $this->db->fetch_object($resql);
1021 $c = new Categorie($this->db);
1022 $c->fetch($obj->rowid);
1023 $ways = $c->print_all_ways(); // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formatted text
1024 foreach ($ways as $way) {
1025 $toprint[] = '<li>' . img_object('', 'category') . ' ' . $way . '</li>';
1026 }
1027 $value = '<div><ul>' . implode(' ', $toprint) . '</ul></div>';
1028 }
1029 } else {
1030 dol_syslog(__METHOD__ . ' error ' . $this->db->lasterror(), LOG_WARNING);
1031 }
1032 } elseif ($type == 'radio') {
1033 $value = (string) $param['options'][$value];
1034 } elseif ($type == 'checkbox') {
1035 $value_arr = explode(',', $value);
1036 $value = '';
1037 if (is_array($value_arr) && count($value_arr) > 0) {
1038 $toprint = array();
1039 foreach ($value_arr as $valueval) {
1040 if (!empty($valueval)) {
1041 $toprint[] = '<li>' . $param['options'][$valueval] . '</li>';
1042 }
1043 }
1044 if (!empty($toprint)) {
1045 $value = '<div><ul>' . implode(' ', $toprint) . '</ul></div>';
1046 }
1047 }
1048 } elseif ($type == 'chkbxlst') {
1049 $value_arr = explode(',', $value);
1050
1051 $param_list = array_keys($param['options']);
1052 $InfoFieldList = explode(":", $param_list[0]);
1053
1054 $selectkey = "rowid";
1055 $keyList = 'rowid';
1056
1057 if (count($InfoFieldList) >= 3) {
1058 $selectkey = $InfoFieldList[2];
1059 $keyList = $InfoFieldList[2] . ' as rowid';
1060 }
1061
1062 $fields_label = explode('|', $InfoFieldList[1]);
1063 if (is_array($fields_label)) {
1064 $keyList .= ', ';
1065 $keyList .= implode(', ', $fields_label);
1066 }
1067
1068 $filter_categorie = false;
1069 if (count($InfoFieldList) > 5) {
1070 if ($InfoFieldList[0] == 'categorie') {
1071 $filter_categorie = true;
1072 }
1073 }
1074
1075 $sql = "SELECT " . $this->db->sanitize($keyList);
1076 $sql .= ' FROM ' . $this->db->prefix() . $this->db->sanitize($InfoFieldList[0]);
1077 if (strpos($InfoFieldList[4], 'extra') !== false) {
1078 $sql .= ' as main';
1079 }
1080 // $sql.= " WHERE ".$selectkey."='".$this->db->escape($value)."'";
1081 // $sql.= ' AND entity = '.$conf->entity;
1082
1083 dol_syslog(__METHOD__ . ' type=chkbxlst', LOG_DEBUG);
1084 $resql = $this->db->query($sql);
1085 if ($resql) {
1086 if (!$filter_categorie) {
1087 $value = ''; // value was used, so now we reset it to use it to build final output
1088 $toprint = array();
1089 while ($obj = $this->db->fetch_object($resql)) {
1090 // Several field into label (eq table:code|libelle:rowid)
1091 $fields_label = explode('|', $InfoFieldList[1]);
1092 if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1093 if (is_array($fields_label) && count($fields_label) > 1) {
1094 foreach ($fields_label as $field_toshow) {
1095 $translabel = '';
1096 if (!empty($obj->$field_toshow)) {
1097 $translabel = $langs->trans($obj->$field_toshow);
1098 }
1099 if ($translabel != $field_toshow) {
1100 $toprint[] = '<li>' . dol_trunc($translabel, 18) . '</li>';
1101 } else {
1102 $toprint[] = '<li>' . $obj->$field_toshow . '</li>';
1103 }
1104 }
1105 } else {
1106 $translabel = '';
1107 if (!empty($obj->{$InfoFieldList[1]})) {
1108 $translabel = $langs->trans($obj->{$InfoFieldList[1]});
1109 }
1110 if ($translabel != $obj->{$InfoFieldList[1]}) {
1111 $toprint[] = '<li>' . dol_trunc($translabel, 18) . '</li>';
1112 } else {
1113 $toprint[] = '<li>' . $obj->{$InfoFieldList[1]} . '</li>';
1114 }
1115 }
1116 }
1117 }
1118 } else {
1119 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1120
1121 $toprint = array();
1122 while ($obj = $this->db->fetch_object($resql)) {
1123 if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
1124 $c = new Categorie($this->db);
1125 $c->fetch($obj->rowid);
1126 $ways = $c->print_all_ways(); // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formatted text
1127 foreach ($ways as $way) {
1128 $toprint[] = '<li>' . img_object('', 'category') . ' ' . $way . '</li>';
1129 }
1130 }
1131 }
1132 }
1133 $value = '<div><ul>' . implode(' ', $toprint) . '</ul></div>';
1134 } else {
1135 dol_syslog(__METHOD__ . ' error ' . $this->db->lasterror(), LOG_WARNING);
1136 }
1137 } elseif ($type == 'link') {
1138 // only if something to display (perf)
1139 if ($value) {
1140 $param_list = array_keys($param['options']); // Example: $param_list='ObjectName:classPath:-1::customer'
1141
1142 $InfoFieldList = explode(":", $param_list[0]);
1143 $classname = $InfoFieldList[0];
1144 $classpath = $InfoFieldList[1];
1145 if (!empty($classpath)) {
1146 dol_include_once($InfoFieldList[1]);
1147 if ($classname && class_exists($classname)) {
1148 $object = new $classname($this->db);
1149 '@phan-var-force CommonObject $object';
1151 $result = $object->fetch($value);
1152 $value = '';
1153 if ($result > 0) {
1154 if (property_exists($object, 'label')) {
1155 $value = (string) $object->label; // @phan-suppress-current-line PhanUndeclaredProperty
1156 } elseif (property_exists($object, 'libelle')) {
1157 $value = (string) $object->libelle; // @phan-suppress-current-line PhanUndeclaredProperty
1158 } elseif (property_exists($object, 'nom')) {
1159 $value = (string) $object->nom; // @phan-suppress-current-line PhanUndeclaredProperty
1160 } elseif (property_exists($object, 'ref')) {
1161 $value = (string) $object->ref; // @phan-suppress-current-line PhanUndeclaredProperty
1162 }
1163 }
1164 }
1165 } else {
1166 dol_syslog(__METHOD__ . ' Error bad setup of field', LOG_WARNING);
1167 return 'Error bad setup of field';
1168 }
1169 } else {
1170 $value = '';
1171 }
1172 } elseif ($type == 'password') {
1173 $value = preg_replace('/./i', '*', $value);
1174 } else { // text|html|varchar
1175 $value = dol_htmlentitiesbr($value);
1176 }
1177
1178 $out = $value;
1179
1180 return $out;
1181 }
1182
1196 public function inputType($type, $name, $value = '', $id = '', $morecss = '', $moreparam = '', $label = '', $addInputLabel = '')
1197 {
1198 $out = '';
1199 if ($label != '') {
1200 $out .= '<label for="' . dolPrintHTMLForAttribute($id) . '">';
1201 }
1202 $out .= '<input type="' . dolPrintHTMLForAttribute($type) . '"';
1203 $out .= ' class="flat valignmiddle maxwidthonsmartphone ' . dolPrintHTMLForAttribute($morecss) . '"';
1204 if ($id != '') {
1205 $out .= ' id="' . dolPrintHTMLForAttribute($id) . '"';
1206 }
1207 $out .= ' name="' . dolPrintHTMLForAttribute($name) . '"';
1208 $out .= ' value="' . dolPrintHTMLForAttribute($value) . '" ';
1209 $out .= ($moreparam ? ' ' . $moreparam : '');
1210 $out .= ' />' . $addInputLabel;
1211 if ($label != '') {
1212 $out .= $label . '</label>';
1213 }
1214
1215 return $out;
1216 }
1217
1230 public function inputSelectAjax($htmlName, $array, $id, $ajaxUrl, $ajaxData = [], $morecss = 'minwidth75', $moreparam = '')
1231 {
1232 $out = "
1233 <script>
1234 $(document).ready(function () {
1235 $('#" . dol_escape_js($htmlName) . "').select2({
1236 ajax: {
1237 url: '" . dol_escape_js($ajaxUrl) . "',
1238 dataType: 'json',
1239 delay: 250, // wait 250 milliseconds before triggering the request
1240 data: function (params) {
1241 var query = {
1242 search: params.term,
1243 page: params.page || 1";
1244 if (!empty($ajaxData) && is_array($ajaxData)) {
1245 foreach ($ajaxData as $key => $value) {
1246 $out .= ", " . preg_replace('/[^a-z0-9_]/i', '', $key) . ": '" . dol_escape_js($value) . "'";
1247 }
1248 }
1249 $out .= "
1250 }
1251 return query;
1252 }
1253 }
1254 })
1255 });
1256 </script>";
1257
1258 $out .= $this->selectarray($htmlName, $array, $id, 0, 0, 0, $moreparam, 0, 0, 0, '', $morecss);
1259
1260 return $out;
1261 }
1262
1272 public function inputHtml($htmlName, $value, $morecss = '', $moreparam = '')
1273 {
1274 require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
1275 $doleditor = new DolEditor($htmlName, $value, '', 200, 'dolibarr_notes', 'In', false, false, isModEnabled('fckeditor') && getDolGlobalInt('FCKEDITOR_ENABLE_SOCIETE'), ROWS_5, '90%');
1276
1277 return (string) $doleditor->Create(1, '', true, '', '', $moreparam, $morecss);
1278 }
1279
1290 public function inputText($htmlName, $value, $morecss = '', $moreparam = '', $options = array())
1291 {
1292 global $langs;
1293 $out = '';
1294 if (!empty($options)) {
1295 // If the textarea field has a list of arrayofkeyval into its definition, we suggest a combo with possible values to fill the textarea.
1296 $out .= '<div class="text-area-multi-input-add-group" >';
1297 $out .= $this->selectarray($htmlName . "_multiinput", $options, '', 1, 0, 0, $moreparam, 0, 0, 0, '', "flat maxwidthonphone" . $morecss);
1298 $out .= '<input id="' . $htmlName . '_multiinputadd" type="button" class="button" value="' . $langs->trans("Add") . '">';
1299 $out .= '</div>';
1300 $out .= "<script>";
1301 $out .= '
1302 function handlemultiinputdisabling(htmlname){
1303 console.log("We handle the disabling of used options for "+htmlname+"_multiinput");
1304 multiinput = $("#"+htmlname+"_multiinput");
1305 multiinput.find("option").each(function(){
1306 tmpval = $("#"+htmlname).val();
1307 tmpvalarray = tmpval.split("\n");
1308 valtotest = $(this).val();
1309 if(tmpvalarray.includes(valtotest)){
1310 $(this).prop("disabled",true);
1311 } else {
1312 if($(this).prop("disabled") == true){
1313 console.log(valtotest)
1314 $(this).prop("disabled", false);
1315 }
1316 }
1317 });
1318 }
1319
1320 $(document).ready(function () {
1321 $("#' . $htmlName . '_multiinputadd").on("click",function() {
1322 tmpval = $("#' . $htmlName . '").val();
1323 tmpvalarray = tmpval.split(",");
1324 valtotest = $("#' . $htmlName . '_multiinput").val();
1325 if(valtotest != -1 && !tmpvalarray.includes(valtotest)){
1326 console.log("We add the selected value to the text area ' . $htmlName . '");
1327 if(tmpval == ""){
1328 tmpval = valtotest;
1329 } else {
1330 tmpval = tmpval + "\n" + valtotest;
1331 }
1332 $("#' . $htmlName . '").val(tmpval);
1333 handlemultiinputdisabling("' . $htmlName . '");
1334 $("#' . $htmlName . '_multiinput").val(-1);
1335 } else {
1336 console.log("We add nothing the text area ' . $htmlName . '");
1337 }
1338 });
1339 $("#' . $htmlName . '").on("change",function(){
1340 handlemultiinputdisabling("' . $htmlName . '");
1341 });
1342 handlemultiinputdisabling("' . $htmlName . '");
1343 })';
1344 $out .= "</script>";
1345 $value = str_replace(',', "\n", $value);
1346 }
1347
1348 require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
1349 $doleditor = new DolEditor($htmlName, (string) $value, '', 200, 'dolibarr_notes', 'In', false, false, false, ROWS_5);
1350 $out .= (string) $doleditor->Create(1, '', true, '', '', $moreparam, $morecss);
1351
1352 return $out;
1353 }
1354
1365 public function inputRadio($htmlName, $options, $selectedValue, $morecss = '', $moreparam = '')
1366 {
1367 $out = '';
1368 foreach ($options as $optionKey => $optionLabel) {
1369 $selected = ((string) $selectedValue) === ((string) $optionKey) ? ' checked="checked"' : '';
1370 $optionId = $htmlName . '_' . $optionKey;
1371 $out .= '<input class="flat' . $morecss . '" type="radio" name="' . $htmlName . '" id="' . $optionId . '" value="' . dolPrintHTMLForAttribute((string) $optionKey) . '"' . $selected . $moreparam . '/><label for="' . $optionId . '">' . $optionLabel . '</label><br>';
1372 }
1373
1374 return $out;
1375 }
1376
1387 public function inputStars($htmlName, $size, $value, $morecss = '', $moreparam = '')
1388 {
1389 $out = '<input type="hidden" class="flat ' . $morecss . '" name="' . $htmlName . '" id="' . $htmlName . '" value="' . dolPrintHTMLForAttribute((string) $value) . '"' . $moreparam . '>';
1390 $out .= '<div class="star-selection" id="' . $htmlName . '_selection">';
1391 for ($i = 1; $i <= $size; $i++) {
1392 $out .= '<span class="star" data-value="' . $i . '">' . img_picto('', 'fontawesome_star_fas') . '</span>';
1393 }
1394 $out .= '</div>';
1395 $out .= '<script>
1396 jQuery(function($) { /* commonobject.class.php 1 */
1397 let container = $("#' . $htmlName . '_selection");
1398 let selectedStars = parseInt($("#' . $htmlName . '").val()) || 0;
1399 container.find(".star").each(function() {
1400 $(this).toggleClass("active", $(this).data("value") <= selectedStars);
1401 });
1402 container.find(".star").on("mouseover", function() {
1403 let selectedStar = $(this).data("value");
1404 container.find(".star").each(function() {
1405 $(this).toggleClass("active", $(this).data("value") <= selectedStar);
1406 });
1407 });
1408 container.on("mouseout", function() {
1409 container.find(".star").each(function() {
1410 $(this).toggleClass("active", $(this).data("value") <= selectedStars);
1411 });
1412 });
1413 container.find(".star").off("click").on("click", function() {
1414 selectedStars = $(this).data("value");
1415 if (selectedStars === 1 && $("#' . $htmlName . '").val() == 1) {
1416 selectedStars = 0;
1417 }
1418 $("#' . $htmlName . '").val(selectedStars);
1419 container.find(".star").each(function() {
1420 $(this).toggleClass("active", $(this).data("value") <= selectedStars);
1421 });
1422 });
1423 });
1424 </script>';
1425
1426 return $out;
1427 }
1428
1438 public function inputIcon($htmlName, $value, $morecss = '', $moreparam = '')
1439 {
1440 global $langs;
1441
1442 /* External lib inclusion are not allowed in backoffice. Also lib is included several time if there is several icon file.
1443 Some code must be added into main when MAIN_ADD_ICONPICKER_JS is set to add of lib in html header
1444 $out ='<link rel="stylesheet" href="'.dol_buildpath('/myfield/css/fontawesome-iconpicker.min.css', 1).'">';
1445 $out.='<script src="'.dol_buildpath('/myfield/js/fontawesome-iconpicker.min.js', 1).'"></script>';
1446 */
1447 $out = '<input type="text" class="form-control icp icp-auto iconpicker-element iconpicker-input flat ' . $morecss . ' maxwidthonsmartphone"';
1448 $out .= ' name="' . $htmlName . '" id="' . $htmlName . '" value="' . dolPrintHTMLForAttribute((string) $value) . '" ' . ((string) $moreparam) . '>';
1449 if (getDolGlobalInt('MAIN_ADD_ICONPICKER_JS')) {
1450 $out .= '<script>';
1451 $options = "{ title: '<b>" . $langs->trans("IconFieldSelector") . "</b>', placement: 'right', showFooter: false, templates: {";
1452 $options .= "iconpicker: '<div class=\"iconpicker\"><div style=\"background-color:#EFEFEF;\" class=\"iconpicker-items\"></div></div>',";
1453 $options .= "iconpickerItem: '<a role=\"button\" href=\"#\" class=\"iconpicker-item\" style=\"background-color:#DDDDDD;\"><i></i></a>',";
1454 // $options.="buttons: '<button style=\"background-color:#FFFFFF;\" class=\"iconpicker-btn iconpicker-btn-cancel btn btn-default btn-sm\">".$langs->trans("Cancel")."</button>";
1455 // $options.="<button style=\"background-color:#FFFFFF;\" class=\"iconpicker-btn iconpicker-btn-accept btn btn-primary btn-sm\">".$langs->trans("Save")."</button>',";
1456 $options .= "footer: '<div class=\"popover-footer\" style=\"background-color:#EFEFEF;\"></div>',";
1457 $options .= "search: '<input type=\"search\" class\"form-control iconpicker-search\" placeholder=\"" . $langs->trans("TypeToFilter") . "\" />',";
1458 $options .= "popover: '<div class=\"iconpicker-popover popover\">";
1459 $options .= " <div class=\"arrow\" ></div>";
1460 $options .= " <div class=\"popover-title\" style=\"text-align:center;background-color:#EFEFEF;\"></div>";
1461 $options .= " <div class=\"popover-content \" ></div>";
1462 $options .= "</div>'}}";
1463 $out .= "$('#" . $htmlName . "').iconpicker(" . $options . ");";
1464 $out .= '</script>';
1465 }
1466
1467 return $out;
1468 }
1469
1478 public function inputGeoPoint($htmlName, $value, $type = '')
1479 {
1480 require_once DOL_DOCUMENT_ROOT . '/core/class/dolgeophp.class.php';
1481 require_once DOL_DOCUMENT_ROOT . '/core/class/geomapeditor.class.php';
1482 $dolgeophp = new DolGeoPHP($this->db);
1483 $geomapeditor = new GeoMapEditor();
1484
1485 $geojson = '{}';
1486 $centroidjson = getDolGlobalString('MAIN_INFO_SOCIETE_GEO_COORDINATES', '{}');
1487 if (!empty($value)) {
1488 $tmparray = $dolgeophp->parseGeoString($value);
1489 $geojson = $tmparray['geojson'];
1490 $centroidjson = $tmparray['centroidjson'];
1491 }
1492
1493 return $geomapeditor->getHtml($htmlName, $geojson, $centroidjson, $type);
1494 }
1495
1502 public function outputMultiValues($values)
1503 {
1504 $out = '';
1505 $toPrint = array();
1506 $values = is_array($values) ? $values : array();
1507
1508 foreach ($values as $value) {
1509 $toPrint[] = '<li class="select2-search-choice-dolibarr noborderoncategories" style="background: #bbb">' . $value . '</li>';
1510 }
1511 if (!empty($toPrint)) {
1512 $out = '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">' . implode(' ', $toPrint) . '</ul></div>';
1513 }
1514
1515 return $out;
1516 }
1517
1525 public function outputStars($size, $value)
1526 {
1527 $out = '<div class="star-selection" data-value="' . dolPrintHTMLForAttribute((string) $value) . '">';
1528 for ($i = 1; $i <= $size; $i++) {
1529 $out .= '<span class="star' . ($i <= $value ? ' active' : '') . '" data-value="' . $i . '">' . img_picto('', 'fontawesome_star_fas') . '</span>';
1530 }
1531 $out .= '</div>';
1532
1533 return $out;
1534 }
1535
1542 public function outputIcon($value)
1543 {
1544 $out = '<span class="' . dolPrintHTMLForAttribute((string) $value) . '"></span>';
1545
1546 return $out;
1547 }
1548
1556 public function outputGeoPoint($value, $type)
1557 {
1558 $out = '';
1559
1560 if (!empty($value)) {
1561 require_once DOL_DOCUMENT_ROOT . '/core/class/dolgeophp.class.php';
1562 $dolgeophp = new DolGeoPHP($this->db);
1563 if ($type == 'point') {
1564 $out = $dolgeophp->getXYString($value);
1565 } else { // multipts, linestrg, polygon
1566 $out = $dolgeophp->getPointString($value);
1567 }
1568 }
1569
1570 return $out;
1571 }
1572
1587 public function getNomUrl(&$object, $withpicto = 0, $option = '', $maxlength = 0, $save_lastsearch_value = -1, $notooltip = 0, $morecss = '', $add_label = 0, $sep = ' - ')
1588 {
1589 if (is_object($object) && method_exists($object, 'getNomUrl')) {
1590 $out = $object->getNomUrl($withpicto, $option, $maxlength, $save_lastsearch_value, $notooltip, $morecss, $add_label, $sep);
1591 $out = dol_string_nohtmltag($out);
1592 return $out;
1593 } else {
1594 return '';
1595 }
1596 }
1597
1616 public static function showphoto($modulepart, $object, $width = 100, $height = 0, $caneditfield = 0, $cssclass = 'photowithmargin', $imagesize = '', $addlinktofullsize = 1, $cache = 0, $forcecapture = '', $noexternsourceoverwrite = 0, $usesharelinkifavailable = 0)
1617 {
1618 $out = parent::showphoto($modulepart, $object, $width, $height, $caneditfield, $cssclass, $imagesize, $addlinktofullsize, $cache, $forcecapture, $noexternsourceoverwrite, $usesharelinkifavailable);
1619 $out = self::convertAllLink($out);
1620
1621 return $out;
1622 }
1623
1640 public function printFieldCell($key, $label, $value, $params = array())
1641 {
1642 $required = !empty($params['required']) ? ' required' : '';
1643 $cell_class = !empty($params['cell_class']) ? ' ' . dolPrintHTMLForAttribute(trim($params['cell_class'])) : '';
1644 $cell_attributes = !empty($params['cell_attributes']) ? ' ' . trim($params['cell_attributes']) : '';
1645 $label_class = !empty($params['label_class']) ? ' ' . dolPrintHTMLForAttribute(trim($params['label_class'])) : '';
1646 $label_attributes = !empty($params['label_attributes']) ? ' ' . trim($params['label_attributes']) : '';
1647 $value_class = !empty($params['value_class']) ? ' ' . dolPrintHTMLForAttribute(trim($params['value_class'])) : '';
1648 $value_attributes = !empty($params['value_attributes']) ? ' ' . trim($params['value_attributes']) : '';
1649
1650 $out = '<div class="grid field_' . dolPrintHTMLForAttribute(strtolower($key)) . $cell_class . '"' . $cell_attributes . '>';
1651 $out .= '<div class="' . $required . $label_class . '"' . $label_attributes . '>';
1652 $out .= $label;
1653 $out .= '</div>';
1654 $out .= '<div class="' . $value_class . '"' . $value_attributes . '>';
1655 $out .= $value;
1656 $out .= '</div>';
1657 $out .= '</div>';
1658
1659 return $out;
1660 }
1661
1670 public static function convertAllLink($html, $additionalViewImageParams = '', $additionalDocumentParams = '')
1671 {
1672 require_once DOL_DOCUMENT_ROOT . '/webportal/class/context.class.php';
1674
1675 $html = str_replace(DOL_URL_ROOT . '/viewimage.php?', $context->getControllerUrl('viewimage') . $additionalViewImageParams . '&', $html);
1676 $html = str_replace(urlencode(dol_escape_js(DOL_URL_ROOT . '/viewimage.php?')), urlencode(dol_escape_js($context->getControllerUrl('viewimage') . $additionalViewImageParams . '&')), $html);
1677 $html = str_replace(DOL_URL_ROOT . '/document.php?', $context->getControllerUrl('document') . $additionalDocumentParams . '&', $html);
1678 $html = str_replace(urlencode(dol_escape_js(DOL_URL_ROOT . '/document.php?')), urlencode(dol_escape_js($context->getControllerUrl('document') . $additionalDocumentParams . '&')), $html);
1679
1680 return $html;
1681 }
1682
1692 public function selectCurrency($selected = '', $htmlname = 'currency_id', $mode = 0, $useempty = '')
1693 {
1694
1695 return '<span class="form-select-currency-container">'.parent::selectCurrency($selected, $htmlname, $mode, $useempty).'</span>';
1696 }
1697}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
$c
Definition line.php:334
Class to manage categories.
static getInstance()
Singleton method to create one instance of this object.
Class to manage a WYSIWYG editor.
Class to manage Geo processing Usage: $dolgeophp=new DolGeoPHP($db);.
Class to manage generation of HTML components Only common components must be here.
selectDate($set_time='', $prefix='re', $h=0, $m=0, $empty=0, $form_name="", $d=1, $addnowlink=0, $disabled=0, $fullday='', $addplusone='', $adddateof='', $openinghours='', $stepminutes=1, $labeladddateof='', $placeholder='', $gm='auto', $calendarpicto='')
Show a HTML widget to input a date or combo list for day, month, years and optionally hours and minut...
selectForFormsList($objecttmp, $htmlname, $preselectedvalue, $showempty='', $searchkey='', $placeholder='', $morecss='', $moreparams='', $forcecombo=0, $outputmode=0, $disabled=0, $sortfield='', $filter='', $sortorder='ASC')
Output html form to select an object.
Class to manage generation of HTML components Only common components for WebPortal must be here.
inputType($type, $name, $value='', $id='', $morecss='', $moreparam='', $label='', $addInputLabel='')
Html for input with label.
printFieldCell($key, $label, $value, $params=array())
Return HTML code of the cell.
selectCurrency($selected='', $htmlname='currency_id', $mode=0, $useempty='')
Retourne la liste des devises, dans la langue de l'utilisateur.
inputDate($name, $value='', $placeholder='', $id='', $morecss='', $moreparam='')
Input for date.
inputHtml($htmlName, $value, $morecss='', $moreparam='')
Html for HTML area.
inputStars($htmlName, $size, $value, $morecss='', $moreparam='')
Html for input stars.
getDocumentsLink($modulepart, $modulesubdir, $filedir, $filter='', $morecss='', $allfiles=0)
Show a Document icon with link(s) You may want to call this into a div like this: print '.
static convertAllLink($html, $additionalViewImageParams='', $additionalDocumentParams='')
Convert all link of the provided html output.
outputMultiValues($values)
Html for show selected multiple values.
showInputFieldForObject($object, $val, $key, $value, $moreparam='', $keysuffix='', $keyprefix='', $morecss='')
Return HTML string to put an input field into a page Code very similar with showInputField for common...
outputStars($size, $value)
Html for show stars.
inputSelectAjax($htmlName, $array, $id, $ajaxUrl, $ajaxData=[], $morecss='minwidth75', $moreparam='')
Html for select with get options by AJAX.
outputGeoPoint($value, $type)
Html for show geo point.
outputIcon($value)
Html for show icon.
selectForForms($objectdesc, $htmlname, $preselectedvalue, $showempty='', $searchkey='', $placeholder='', $morecss='', $moreparams='', $forcecombo=0, $disabled=0, $selected_input_value='', $objectfield='')
Generic method to select a component from a combo list.
inputGeoPoint($htmlName, $value, $type='')
Html for input geo point.
getSignatureLink($modulepart, $object, $morecss='')
Show a Signature icon with link You may want to call this into a div like this: print '.
inputIcon($htmlName, $value, $morecss='', $moreparam='')
Html for input icon.
inputRadio($htmlName, $options, $selectedValue, $morecss='', $moreparam='')
Html for input radio.
__construct($db)
Constructor.
static selectarray($htmlname, $array, $id='', $show_empty=0, $key_in_label=0, $value_as_key=0, $moreparam='', $translate=0, $maxlen=0, $disabled=0, $sort='', $morecss='minwidth75', $addjscombo=1, $moreparamonempty='', $disablebademail=0, $nohtmlescape=0)
Return a HTML select string, built from an array of key+value.
getNomUrl(&$object, $withpicto=0, $option='', $maxlength=0, $save_lastsearch_value=-1, $notooltip=0, $morecss='', $add_label=0, $sep=' - ')
Return link of object.
inputText($htmlName, $value, $morecss='', $moreparam='', $options=array())
Html for HTML area.
static showphoto($modulepart, $object, $width=100, $height=0, $caneditfield=0, $cssclass='photowithmargin', $imagesize='', $addlinktofullsize=1, $cache=0, $forcecapture='', $noexternsourceoverwrite=0, $usesharelinkifavailable=0)
Return HTML code to output a photo.
Class to manage a Leaflet map width geometrics objects.
convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengthOfWeek=7)
Return, in clear text, value of a number of seconds in days, hours and minutes.
Definition date.lib.php:248
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:64
dol_print_ip($ip, $mode=0, $showname=0)
Return an IP formatted to be shown on screen.
dol_print_phone($phone, $countrycode='', $contactid=0, $socid=0, $addlink='', $separ="&nbsp;", $withpicto='', $titlealt='', $adddivfloat=0, $morecss='paddingright')
Format phone numbers according to country.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
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.
img_mime($file, $titlealt='', $morecss='')
Show MIME img of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into JavaScript code.
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
dolPrintHTMLForAttribute($s, $escapeonlyhtmltags=0, $allowothertags=array())
Return a string ready to be output into an HTML attribute (alt, title, data-html, ....
dol_print_email($email, $contactid=0, $socid=0, $addlink=0, $max=0, $showinvalid=1, $withpicto=0, $morecss='paddingrightonly')
Show EMail link formatted for HTML output.
getDolCurrency()
Return the main currency ('EUR', 'USD', ...)
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
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...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
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...
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
$context
@method int call_trigger(string $triggerName, ?User $user)
Definition logout.php:42