diff --git a/htdocs/core/ajax/ajaxfield.php b/htdocs/core/ajax/ajaxfield.php new file mode 100644 index 00000000000..8eb40de4a42 --- /dev/null +++ b/htdocs/core/ajax/ajaxfield.php @@ -0,0 +1,150 @@ + + * Copyright (C) 2024 Frédéric France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/ajax/ajaxfield.php + * \ingroup core + * \brief This script returns content of extrafield. See extrafield to update value. + */ + +if (!defined('NOTOKENRENEWAL')) { + // Disables token renewal + define('NOTOKENRENEWAL', 1); +} +if (!defined('NOREQUIREMENU')) { + define('NOREQUIREMENU', '1'); +} +if (!defined('NOREQUIREHTML')) { + define('NOREQUIREHTML', '1'); +} +if (!defined('NOREQUIREAJAX')) { + define('NOREQUIREAJAX', '1'); +} +if (!defined('NOHEADERNOFOOTER')) { + define('NOHEADERNOFOOTER', '1'); +} + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/fieldsmanager.class.php'; + +/** + * @var Conf $conf + * @var DoliDB $db + * @var Translate $langs + * @var User $user + */ + +// object id +$objectid = GETPOST('objectid', 'aZ09'); +// 'module' or 'myobject@mymodule', 'mymodule_myobject' +$objecttype = GETPOST('objecttype', 'aZ09arobase'); +$objectkey = GETPOST('objectkey', 'restricthtml'); +$search = GETPOST('search', 'restricthtml'); +$page = GETPOSTINT('page'); +$mode = GETPOST('mode', 'aZ09'); +$value = GETPOST('value', 'alphanohtml'); +$dependencyvalue = GETPOST('dependencyvalue', 'alphanohtml'); +$limit = 10; +$element_ref = ''; +if (is_numeric($objectid)) { + $objectid = (int) $objectid; +} else { + $element_ref = $objectid; + $objectid = 0; +} +// Load object according to $element +$object = fetchObjectByElement($objectid, $objecttype, $element_ref); +if (empty($object->element)) { + httponly_accessforbidden('Failed to get object with fetchObjectByElement(id=' . $objectid . ', objecttype=' . $objecttype . ')'); +} + +$module = $object->module; +$element = $object->element; + +$usesublevelpermission = ($module != $element ? $element : ''); +if ($usesublevelpermission && !$user->hasRight($module, $element)) { // There is no permission on object defined, we will check permission on module directly + $usesublevelpermission = ''; +} + +// print $object->id.' - '.$object->module.' - '.$object->element.' - '.$object->table_element.' - '.$usesublevelpermission."\n"; + +// Security check +restrictedArea($user, $object->module, $object, $object->table_element, $usesublevelpermission); + + +/* + * View + */ + +top_httphead(); + +$data = [ + 'results' => [], + 'pagination' => [ + 'more' => true, + ] +]; +$nbResult = 0; +if ($object instanceof CommonObject) { + $extrafields = new ExtraFields($db); + $extrafields->fetch_name_optionals_label($object->table_element); + + $fieldManager = new FieldsManager($db); + $fieldInfos = $fieldManager->getFieldsInfos($objectkey, $object, $extrafields, $mode); + $field = $fieldManager->getFieldClass($fieldInfos->type); + if (isset($field)) { + if (method_exists($field, 'getOptions')) { + $fieldInfos->optionsSqlPage = $page; + $fieldInfos->optionsSqlLimit = $limit; + if ($dependencyvalue !== '') { + $fieldInfos->optionsSqlDependencyValue = $dependencyvalue; + } + + /** + * @var CommonSellistField $field + */ + '@phan-var-force CommonSellistField $field'; + $options = $field->getOptions($fieldInfos, $objectkey, $page == 1, true); + if (is_array($options)) { + $nbResult = count($options); + foreach ($options as $key => $option) { + $data['results'][] = [ + 'id' => $key, + 'text' => $option['label'], + ]; + } + } else { + dol_syslog('htdocs/core/ajax/ajaxfield.php ' . $field->errorsToString(), LOG_ERR); + } + } else { + dol_syslog('htdocs/core/ajax/ajaxfield.php method getOptions() don\'t exist in class ' . get_class($field), LOG_ERR); + } + } else { + dol_syslog('htdocs/core/ajax/ajaxfield.php ' . $fieldManager->errorsToString(), LOG_ERR); + } +} + +if ($page > 1 && $nbResult < 10) { + $data['pagination'] = [ + 'more' => false, + ]; +} +print json_encode($data); + +$db->close(); diff --git a/htdocs/core/class/fieldinfos.class.php b/htdocs/core/class/fieldinfos.class.php new file mode 100644 index 00000000000..86b9369138e --- /dev/null +++ b/htdocs/core/class/fieldinfos.class.php @@ -0,0 +1,325 @@ + + * Copyright (C) 2002-2003 Jean-Louis Bergamo + * Copyright (C) 2004 Sebastien Di Cintio + * Copyright (C) 2004 Benoit Mortier + * Copyright (C) 2009-2012 Laurent Destailleur + * Copyright (C) 2009-2012 Regis Houssin + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2015 Charles-Fr BENKE + * Copyright (C) 2016 Raphaël Doursenaud + * Copyright (C) 2017 Nicolas ZABOURI + * Copyright (C) 2018-2022 Frédéric France + * Copyright (C) 2022 Antonin MARCHAL + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fieldinfos.class.php + * \ingroup core + * \brief File of class to stock field infos + */ + + +/** + * Class to stock field infos + */ +class FieldInfos +{ + /** + * @var CommonObject|null Object handler (by reference) + */ + public $object = null; + + /** + * @var string Display mode ('create', 'edit', 'view', 'list') + */ + public $mode = ''; + + /** + * @var int Type origin (object or extra field) + */ + public $fieldType = self::FIELD_TYPE_OBJECT; + + /** + * @var string Key name of the field + */ + public $key = ''; + + /** + * @var string Field origin type + * 'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]', + * 'select' (list of values are in 'options'. for integer list of values are in 'arrayofkeyval'), + * 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:CategoryIdType[:CategoryIdList[:SortField]]]]]]', + * 'chkbxlst:...', + * 'varchar(x)', + * 'text', 'text:none', 'html', + * 'double(24,8)', 'real', 'price', 'stock', + * 'date', 'datetime', 'timestamp', 'duration', + * 'boolean', 'checkbox', 'radio', 'array', + * 'email', 'phone', 'url', 'password', 'ip' + * Note: Filter must be a Dolibarr Universal Filter syntax string. Example: "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.status:!=:0) or (t.nature:is:NULL)" + */ + public $originType = ''; + + /** + * @var string Field type (The type name. ex: int, varchar, sellist, boolean, ... ) Used as class name, each type have this class. Ex: IntField, ... + */ + public $type = ''; + + /** + * @var string|null Name of the field in the class + */ + public $nameInClass = null; + + /** + * @var string|null Name of the field in the table + */ + public $nameInTable = null; + + /** + * @var string Field label (the translation key) + */ + public $label = ''; + + /** + * @var string Language file to load + */ + public $langFile = ''; + + /** + * @var string Field picto (code of a picto to show before value in forms) + */ + public $picto = ''; + + /** + * @var int Field position + */ + public $position = 0; + + /** + * @var bool Field required + */ + public $required = false; + + /** + * @var bool Field visible + */ + public $visible = true; + + /** + * @var bool Field visible in the header + */ + public $showOnHeader = false; + + /** + * @var bool Field editable + */ + public $editable = true; + + /** + * @var bool|null Field always editable + */ + public $alwaysEditable = null; + + /** + * @var string Field default value (to be converted in function of the type of the field) + */ + public $defaultValue = ''; + + /** + * @var int|null Field string min length + */ + public $minLength = null; + + /** + * @var int|null Field string max length + */ + public $maxLength = null; + + /** + * @var double|null Field numeric min value + */ + public $minValue = null; + + /** + * @var double|null Field numeric max value + */ + public $maxValue = null; + + /** + * @var string Field size (Example: 255, '24,8') + */ + public $size = ''; + + /** + * @var array Field options (for select, sellist, ...) + */ + public $options = array(); + + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(); + + /** + * @var string Specific check for GETPOST() when get field value (for type 'text' and 'html') + */ + public $getPostCheck = ''; + + /** + * @var string CSS for the input field + */ + public $css = ''; + + /** + * @var string CSS for the td + */ + public $tdCss = ''; + + /** + * @var string CSS for the input field in view mode + */ + public $viewCss = ''; + + /** + * @var string CSS for the input field in list + */ + public $listCss = ''; + + /** + * @var string Input placeholder + */ + public $inputPlaceholder = ''; + + /** + * @var string Field help + */ + public $help = ''; + + /** + * @var string Field comment. Is not used. You can store here any text of your choice. It is not used by application. + */ + public $comment = ''; + + /** + * @var string Prompt for AI + */ + public $aiPrompt = ''; + + /** + * @var bool If value of the field must be visible into the label of the combobox that list record + */ + public $showOnComboBox = false; + + /** + * @var bool If displayed in documents + */ + public $printable = false; + + /** + * @var bool If field set to null on clone + */ + public $emptyOnClone = false; + + /** + * @var bool If value must be unique + */ + public $unique = false; + + /** + * @var string If value is computed. (eval the provided string) + */ + public $computed = ''; + + /** + * @var bool Field must be validated + */ + public $validateField = false; + + /** + * @var int Is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto after value) + */ + public $copyToClipboard = 0; + + /** + * @var bool Disable the input + */ + public $inputDisabled = false; + + /** + * @var bool Autofocus on the input + */ + public $inputAutofocus = false; + + /** + * @var bool Multi input on text type + */ + public $multiInput = false; + + /** + * @var string Field help in list + */ + public $listHelp = ''; + + /** + * @var bool Add total in list footer + */ + public $listTotalizable = false; + + /** + * @var bool Field checked in the list + */ + public $listChecked = true; + + /** + * @var string|null Alias table used for sql request (ex 't.') + */ + public $sqlAlias = null; + + /** + * @var string|null Dependency value (used for filter list from ajax) + */ + public $optionsSqlDependencyValue = null; + + /** + * @var int|null Current page when get sql result for options on 'sellist' and 'chkbxlst' field type + */ + public $optionsSqlPage = null; + + /** + * @var int|null Current offset when get sql result for options on 'sellist' and 'chkbxlst' field type + */ + public $optionsSqlOffset = null; + + /** + * @var int|null Current limit when get sql result for options on 'sellist' and 'chkbxlst' field type + */ + public $optionsSqlLimit = null; + + /** + * @var string|null getNameUrl() parameters 'xxx:xxx:xxx:...' + */ + public $getNameUrlParams = null; + + /** + * @var array Other parameters + */ + public $otherParams = array(); + + + const FIELD_TYPE_OBJECT = 0; + const FIELD_TYPE_EXTRA_FIELD = 1; +} diff --git a/htdocs/core/class/fields/booleanfield.class.php b/htdocs/core/class/fields/booleanfield.class.php new file mode 100644 index 00000000000..fb768b1703a --- /dev/null +++ b/htdocs/core/class/fields/booleanfield.class.php @@ -0,0 +1,243 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/booleanfield.class.php + * \ingroup core + * \brief File of class to boolean field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to boolean field + */ +class BooleanField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array('', '-1', -1); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->selectyesno($htmlName, $value, 1, false, 1, 1, 'width75 yesno'); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $checked = empty($value) ? '' : ' checked="checked"'; + $htmlName = $keyPrefix . $key . $keySuffix; + + $out = self::$form->inputType('checkbox', $htmlName, '1', $htmlName, $moreCss, $moreAttrib . $checked); + $out .= self::$form->inputType('hidden', $htmlName . '_boolean', '1'); // A hidden field ending with "_boolean" that is always set to 1. + + return $out; + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER') < 2) { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $checked = empty($value) ? '' : ' checked="checked"'; + $value = self::$form->inputType('checkbox', '', '1', '', $moreCss, $checked . $moreAttrib . ' readonly disabled'); + } else { + $value = yn($value ? 1 : 0); + } + + return $value; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + if (empty($moreCss)) $moreCss = $defaultCss; + $moreCss = trim((string) $moreCss); + + return empty($moreCss) ? '' : ' ' . $moreCss; + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isBool($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + // We test on a hidden field named "..._boolean" that is always set to 1 if param is in form so + // when nothing is provided we can make a difference between noparam in the form and param was set to nothing. + if (!GETPOSTISSET($htmlName . "_boolean")) { + $value = $defaultValue; + } elseif (GETPOSTISSET($htmlName)) { + $value = GETPOSTINT($htmlName) == 1 ? 1 : 0; + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOSTINT($htmlName); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + $field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key)); + + $sql = " AND (" . $field . " = '" . $this->db->escape($value) . "'"; + if ($value == '0') { + $sql .= " OR " . $field . " IS NULL"; + } + $sql .= ")"; + + return $sql; + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/checkboxfield.class.php b/htdocs/core/class/fields/checkboxfield.class.php new file mode 100644 index 00000000000..ea58047ddad --- /dev/null +++ b/htdocs/core/class/fields/checkboxfield.class.php @@ -0,0 +1,271 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/checkboxfield.class.php + * \ingroup core + * \brief File of class to checkbox field(multiselect) + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonselectfield.class.php'; + + +/** + * Class to checkbox field (multiselect) + */ +class CheckboxField extends CommonSelectField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(array(), ''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return $this->printInputField($fieldInfos, $key, $value, $keyPrefix, $keySuffix, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $conf; + + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $htmlName = $keyPrefix . $key . $keySuffix; + $values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value))); + + $optionsList = array(); + $options = $this->getOptions($fieldInfos, $key); + + return self::$form->multiselectarray($htmlName, $options, $values, 0, 0, $moreCss, 0, 0, $moreAttrib, '', '', (int) (!empty($conf->use_javascript_ajax) && !getDolGlobalString('MAIN_EXTRAFIELDS_DISABLE_SELECT2'))); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $langs; + $values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value))); + + $out = ''; + if (!$this->isEmptyValue($fieldInfos, $values)) { + $options = $this->getOptions($fieldInfos, $key); + $toPrint = array(); + foreach ($values as $val) { + $valueToPrint = null; + foreach ($options as $optionKey => $optionInfos) { + if (((string) $optionKey) == $val) { + $valueToPrint = $optionInfos['label']; + break; + } + } + if (!isset($valueToPrint)) { + $langs->load("errors"); + $valueToPrint = $langs->trans('ErrorRecordNotFound') . ' ( ' . $val . ' )'; + } + $toPrint[] = $valueToPrint; + } + $out = self::$form->outputMultiValues($toPrint); + } + + return $out; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'minwidth400'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + global $langs; + $values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value))); + + $result = parent::verifyFieldValue($fieldInfos, $key, $values); + if ($result && !$this->isEmptyValue($fieldInfos, $values)) { + $options = $this->getOptions($fieldInfos, $key); + foreach ($values as $val) { + $newVal = trim((string) $val); + if (!isset($options[$newVal])) { + self::$validator->error = $langs->trans('RequireValidValue'); + return false; + } + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + $values = GETPOST($htmlName, 'array'); + + return $this->verifyFieldValue($fieldInfos, $key, $values); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $values = GETPOST($htmlName, 'array'); + if (is_array($values)) $values = implode(',', $values); + } else { + $values = $defaultValue; + } + + return $values; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $values = GETPOST($htmlName, 'array'); + } else { + $values = $defaultValue; + } + + return $values; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value) && is_array($value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + $field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key)); + + $tmp = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'"; + return " AND " . $field . " IN (" . $this->db->sanitize($tmp, 1) . ")"; + } + + return ''; + } + + /** + * Get list of options + * + * @param FieldInfos $fieldInfos Array of properties for field to show + * @param string $key Key of field + * @param bool $addEmptyValue Add also empty value if needed + * @param bool $reload Force reload options + * @return array + */ + public function getOptions($fieldInfos, $key, $addEmptyValue = false, $reload = false) + { + return parent::getOptions($fieldInfos, $key, $addEmptyValue, $reload); + } +} diff --git a/htdocs/core/class/fields/chkbxlstfield.class.php b/htdocs/core/class/fields/chkbxlstfield.class.php new file mode 100644 index 00000000000..a88a9badc9c --- /dev/null +++ b/htdocs/core/class/fields/chkbxlstfield.class.php @@ -0,0 +1,288 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/chkbxlstfield.class.php + * \ingroup core + * \brief File of class to chkbxlst field(multiselect) + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonsellistfield.class.php'; + + +/** + * Class to chkbxlst field (multiselect) + */ +class ChkbxlstField extends CommonSellistField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(array(), ''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $conf; + + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $htmlName = $keyPrefix . $key . $keySuffix; + $values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value))); + + $optionsList = array(); + $options = $this->getOptions($fieldInfos, $key); + foreach ($options as $optionKey => $optionInfos) { + $options[$optionKey] = $optionInfos['label']; + } + + return self::$form->multiselectarray($htmlName, $optionsList, $values, 0, 0, $moreCss, 0, 0, $moreAttrib, '', '', (int) (!empty($conf->use_javascript_ajax) && !getDolGlobalString('MAIN_EXTRAFIELDS_DISABLE_SELECT2'))); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $conf; + + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $htmlName = $keyPrefix . $key . $keySuffix; + $values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value))); + + $options = $this->getOptions($fieldInfos, $key); + + return self::$form->multiselectarray($htmlName, $options, $values, 0, 0, $moreCss, 0, 0, $moreAttrib, '', '', (int) (!empty($conf->use_javascript_ajax) && !getDolGlobalString('MAIN_EXTRAFIELDS_DISABLE_SELECT2'))); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value))); + + $out = ''; + if (!$this->isEmptyValue($fieldInfos, $values)) { + $options = $this->getOptions($fieldInfos, $key, false, false, $values); + $optionParams = $this->getOptionsParams($fieldInfos->options); + $isCategory = $optionParams['tableName'] == 'categorie' && !empty($optionParams['categoryType']); + + $toPrint = array(); + foreach ($values as $val) { + $valueToPrint = ''; + $colorToPrint = 'bbb'; + if (isset($options[$val])) { + $valueToPrint = $options[$val]['label']; + + if ($isCategory) { + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $c = new Categorie($this->db); + $c->fetch($val); + $colorToPrint = $c->color ? $c->color : 'bbb'; + $valueToPrint = img_object('', 'category') . ' ' . $valueToPrint; + } + } else { + $valueToPrint = $val; + } + $toPrint[] = '
  • ' . $valueToPrint . '
  • '; + } + if (!empty($toPrint)) { + $out = '
      ' . implode('', $toPrint) . '
    '; + } + } + + return $out; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'minwidth400'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value))); + + $result = parent::verifyFieldValue($fieldInfos, $key, $values); + if ($result && !$this->isEmptyValue($fieldInfos, $values)) { + $optionParams = $this->getOptionsParams($fieldInfos->options); + if (!self::$validator->isInDb($values, $optionParams['tableName'], $optionParams['keyField'])) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + $values = GETPOST($htmlName, 'array'); + + return $this->verifyFieldValue($fieldInfos, $key, $values); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $values = GETPOST($htmlName, 'array'); + if (is_array($values)) $values = implode(',', $values); + } else { + $values = $defaultValue; + } + + return $values; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'array'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!empty($value) && is_array($value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + $field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key)); + + $tmp = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'"; + return " AND " . $field . " IN (" . $this->db->sanitize($tmp, 1) . ")"; + } + + return ''; + } + + /** + * Get list of options + * + * @param FieldInfos $fieldInfos Array of properties for field to show + * @param string $key Key of field + * @param bool $addEmptyValue Add also empty value if needed + * @param bool $reload Force reload options + * @param string|array $selectedValues Only selected values + * @return array + */ + public function getOptions($fieldInfos, $key, $addEmptyValue = false, $reload = false, $selectedValues = array()) + { + return parent::getOptions($fieldInfos, $key, $addEmptyValue, $reload, $selectedValues); + } +} diff --git a/htdocs/core/class/fields/commonfield.class.php b/htdocs/core/class/fields/commonfield.class.php new file mode 100644 index 00000000000..870c29d54e2 --- /dev/null +++ b/htdocs/core/class/fields/commonfield.class.php @@ -0,0 +1,371 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/commonfield.class.php + * \ingroup core + * \brief File of class to common field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/html.form.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/validate.class.php'; + + +/** + * Class to common field + */ +abstract class CommonField +{ + /** + * @var DoliDB Database handler. + */ + public $db; + + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * @var string[] Array of Error code (or message) + */ + public $errors = array(); + + /** + * @var string Type + */ + public $type; + + /** + * @var string Label + */ + public $label; + + /** + * @var Form|null Form handler. + */ + public static $form; + + /** + * @var Validate|null Validate handler. + */ + public static $validator; + + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array('', 0, array()); + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $form, $langs; + + $this->db = $db; + $this->error = ''; + $this->errors = array(); + + // Type and label + $this->type = strtolower(substr(get_class($this), 0, -5)); + $this->label = 'FieldLabel' . ucfirst($this->type); + + if (!isset(self::$form)) { + if (!is_object($form)) { + $form = new Form($this->db); + } + self::setForm($form); + } + + if (!isset(self::$validator)) { + // Use Validate class to allow external Modules to use data validation part instead of concentrate all test here (factoring) or just for reuse + $validator = new Validate($this->db, $langs); + self::setValidator($validator); + } + } + + /** + * Set form used for print the field + * + * @param Form $form Form handler + * @return void + */ + public static function setForm(&$form) + { + self::$form = &$form; + } + + /** + * Set validator used for check the field value + * + * @param Validate $validator Validate handler + * @return void + */ + public static function setValidator(&$validator) + { + self::$validator = &$validator; + } + + /** + * clear errors + * + * @return void + */ + public function clearErrors() + { + $this->error = ''; + $this->errors = array(); + } + + /** + * Method to output saved errors + * + * @param string $separator Separator between each error + * @return string String with errors + */ + public function errorsToString($separator = ', ') + { + return $this->error . (is_array($this->errors) ? (!empty($this->error) ? $separator : '') . implode($separator, $this->errors) : ''); + } + + /** + * Check if the value is deemed as empty + * + * @param FieldInfos $fieldInfos Properties of the field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param array $emptyValues List of value deemed as empty + * @return bool + */ + public function isEmptyValue($fieldInfos, $value, $emptyValues = null) + { + if (!isset($value)) { + return true; + } + + if (!is_array($emptyValues)) { + $emptyValues = !empty($fieldInfos->emptyValues) && is_array($fieldInfos->emptyValues) ? $fieldInfos->emptyValues : $this->emptyValues; + } + + foreach ($emptyValues as $val) { + if ($val === $value) { + return true; + } + } + + return false; + } + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return ''; + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return ''; + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = 'minwidth400') + { + if (empty($moreCss)) { + if (!empty($fieldInfos->css)) { + $moreCss = $fieldInfos->css; + } elseif (!empty($defaultCss)) { + $moreCss = $defaultCss; + } + } + $moreCss = trim((string) $moreCss); + + return empty($moreCss) ? '' : ' ' . $moreCss; + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + global $langs; + + $required = $fieldInfos->required; + $minLength = $fieldInfos->minLength ?? 0; + $maxLength = $fieldInfos->maxLength ?? 0; + //$emptyValues = !empty($fieldInfos->emptyValues) ? $fieldInfos->emptyValues : $this->emptyValues; + + // Clear error + self::$validator->error = ''; + + // Todo move this in validate class ? + // Required test and empty value + if ($this->isEmptyValue($fieldInfos, $value)) { + if ($required) { + self::$validator->error = $langs->trans('RequireANotEmptyValue'); + return false; + } else { + // if no value sent and the field is not mandatory, no need to perform tests + return true; + } + } + + // MIN Size test + if (!empty($minLength) && is_string($value) && !self::$validator->isMinLength($value, $minLength)) { + return false; + } + + // MAX Size test + if (!empty($maxLength) && is_string($value) && !self::$validator->isMaxLength($value, $maxLength)) { + return false; + } + + // Todo move this in validate class ? + // MIN Value test + if (isset($fieldInfos->minValue) && is_numeric($value) && ((double) $value) < $fieldInfos->minValue) { + self::$validator->error = $langs->trans('RequireMinValue', $fieldInfos->minValue); + return false; + } + + // MAX Value test + if (isset($fieldInfos->maxValue) && is_numeric($value) && ((double) $value) > $fieldInfos->maxValue) { + self::$validator->error = $langs->trans('RequireMaxValue', $fieldInfos->maxValue); + return false; + } + + return true; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + return $this->verifyFieldValue($fieldInfos, $key, GETPOST($htmlName, 'restricthtml')); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + return $defaultValue; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + return $defaultValue; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + return ''; + } +} diff --git a/htdocs/core/class/fields/commongeofield.class.php b/htdocs/core/class/fields/commongeofield.class.php new file mode 100644 index 00000000000..0e739bd297e --- /dev/null +++ b/htdocs/core/class/fields/commongeofield.class.php @@ -0,0 +1,195 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/commongeofield.class.php + * \ingroup core + * \brief File of class to common geo field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to common geo field (for linestrg, multipts, point, polygon, ...) + */ +class CommonGeoField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return ''; + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputGeoPoint($htmlName, (string) $value, $fieldInfos->type); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? self::$form->outputGeoPoint((string) $value, $fieldInfos->type) : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + // Todo make the validator test for geo point + return parent::verifyFieldValue($fieldInfos, $key, $value); + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'restricthtml'); + if ($value != '{}') { + require_once DOL_DOCUMENT_ROOT . '/core/class/dolgeophp.class.php'; + $dolgeophp = new DolGeoPHP($this->db); + $value = $dolgeophp->getWkt($value); + } else { + $value = ''; + } + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + return ''; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + return ''; + } +} diff --git a/htdocs/core/class/fields/commonselectfield.class.php b/htdocs/core/class/fields/commonselectfield.class.php new file mode 100644 index 00000000000..e640d33008b --- /dev/null +++ b/htdocs/core/class/fields/commonselectfield.class.php @@ -0,0 +1,96 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/commonselectfield.class.php + * \ingroup core + * \brief File of class to common select field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to common select field + */ +class CommonSelectField extends CommonField +{ + /** + * @var array> Options cached + */ + public static $options = array(); + + /** + * Get list of options + * + * @param FieldInfos $fieldInfos Array of properties for field to show + * @param string $key Key of field + * @param bool $addEmptyValue Add also empty value if needed + * @param bool $reload Force reload options + * @return array + */ + public function getOptions($fieldInfos, $key, $addEmptyValue = false, $reload = false) + { + global $langs; + + if (!isset(self::$options[$key]) || $reload) { + $options = array(); + if (!empty($fieldInfos->options) && is_array($fieldInfos->options)) { + foreach ($fieldInfos->options as $optionKey => $optionLabel) { + $optionKey = (string) $optionKey; + $optionLabel = (string) $optionLabel; + if ($optionKey == '') { + continue; + } + + // Manage dependency list + $fieldValueParent = ''; + if (strpos($optionLabel, "|") !== false) { + list($optionLabel, $valueParent) = explode('|', $optionLabel); + $fieldValueParent = trim($fieldValueParent); + } + + if (empty($optionLabel)) { + $optionLabel = '(not defined)'; + } else { + $optionLabel = $langs->trans($optionLabel); + } + + $options[$optionKey] = array( + 'id' => $optionKey, + 'label' => $optionLabel, + 'parent' => $fieldValueParent, + ); + } + } + if ($addEmptyValue && (!$fieldInfos->required || count($options) > 1)) { + // For preserve the numeric key indexes + $options = array( + '' => array( + 'id' => '', + 'label' => ' ', + 'parent' => '', + ) + ) + $options; + } + + self::$options[$key] = $options; + } + + return self::$options[$key]; + } +} diff --git a/htdocs/core/class/fields/commonsellistfield.class.php b/htdocs/core/class/fields/commonsellistfield.class.php new file mode 100644 index 00000000000..b67805db073 --- /dev/null +++ b/htdocs/core/class/fields/commonsellistfield.class.php @@ -0,0 +1,373 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/commonsellistfield.class.php + * \ingroup core + * \brief File of class to common sellist field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to common sellist field + */ +class CommonSellistField extends CommonField +{ + /** + * @var string Url of the AJAX page for get options of the sellist + */ + public static $ajaxUrl = DOL_URL_ROOT . '/core/ajax/ajaxfield.php'; + + /** + * @var array> Options cached + */ + public static $options = array(); + + /** + * @var array Code mapping from ID. For backward compatibility + */ + const MAP_ID_TO_CODE = array( + 0 => 'product', + 1 => 'supplier', + 2 => 'customer', + 3 => 'member', + 4 => 'contact', + 5 => 'bank_account', + 6 => 'project', + 7 => 'user', + 8 => 'bank_line', + 9 => 'warehouse', + 10 => 'actioncomm', + 11 => 'website_page', + 12 => 'ticket', + 13 => 'knowledgemanagement', + 14 => 'fichinter', + 16 => 'order', + 17 => 'invoice', + 20 => 'supplier_order', + 21 => 'supplier_invoice' + ); + + /** + * Get all parameters in the options + * + * @param array $options Options of the field + * @return array{all:string,tableName:string,labelFullFields:string[],labelFields:string[],labelAlias:string[],keyField:string,parentName:string,parentFullField:string,parentField:string,parentAlias:string,filter:string,categoryType:string,categoryRoots:string,sortField:string} + */ + public function getOptionsParams($options) + { + $options = is_array($options) ? $options : array(); + $paramList = array_keys($options); + $paramList = preg_split('/[\r\n]+/', $paramList[0]); + // 0 : tableName + // 1 : label field name + // 2 : key fields name (if different of rowid) + // optional parameters... + // 3 : key field parent (for dependent lists). (= 'parentName|parentField'; parentName: Name of the input field (ex: ref or options_code); parentField: Name of the field in the table for getting the value) + // Only the value who is equal to the selected value of the parentName input with the value of the parentField is displayed in this select options + // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value. Or use USF on the second line. + // 5 : string category type. This replace the filter. + // 6 : ids categories list separated by comma for category root. This replace the filter. + // 7 : sort field (Don't manage ASC or DESC) + + $all = (string) $paramList[0]; + $InfoFieldList = explode(":", $all, 5); + + // If there is a filter, we extract it by taking all content inside parenthesis. + if (!empty($InfoFieldList[4])) { + $pos = 0; // $pos will be position of ending filter + $parenthesisopen = 0; + while (substr($InfoFieldList[4], $pos, 1) !== '' && ($parenthesisopen || $pos == 0 || substr($InfoFieldList[4], $pos, 1) != ':')) { + if (substr($InfoFieldList[4], $pos, 1) == '(') { + $parenthesisopen++; + } + if (substr($InfoFieldList[4], $pos, 1) == ')') { + $parenthesisopen--; + } + $pos++; + } + $tmpbefore = substr($InfoFieldList[4], 0, $pos); + $tmpafter = substr($InfoFieldList[4], $pos + 1); + $InfoFieldList[4] = $tmpbefore; + if ($tmpafter !== '') { + $InfoFieldList = array_merge($InfoFieldList, explode(':', $tmpafter)); + } + + // Fix better compatibility with some old extrafield syntax filter "(field=123)" + $reg = array(); + if (preg_match('/^\(?([a-z0-9]+)([=<>]+)(\d+)\)?$/i', $InfoFieldList[4], $reg)) { + $InfoFieldList[4] = '(' . $reg[1] . ':' . $reg[2] . ':' . $reg[3] . ')'; + } + } + + $tableName = (string) ($InfoFieldList[0] ?? ''); + $labelFullFields = (string) ($InfoFieldList[1] ?? ''); + // @phpstan-ignore-next-line + $labelFullFields = array_filter(array_map('trim', explode('|', $labelFullFields)), 'strlen'); + $labelFields = array(); + $labelAlias = array(); + foreach ($labelFullFields as $labelFullField) { + $tmp = $this->getSqlFieldInfo($labelFullField); + $labelFields[] = $tmp['field']; + $labelAlias[] = $tmp['alias']; + } + $keyField = (string) ($InfoFieldList[2] ?? ''); + if (empty($keyField)) $keyField = 'rowid'; + $keyFieldParent = (string) ($InfoFieldList[3] ?? ''); + $tmp = array_map('trim', explode('|', $keyFieldParent)); + $parentName = (string) ($tmp[0] ?? ''); + $parentFullField = (string) ($tmp[1] ?? ''); + $tmp = $this->getSqlFieldInfo($parentFullField); + $parentField = $tmp['field']; + $parentAlias = $tmp['alias']; + $filter = (string) ($InfoFieldList[4] ?? ''); + $categoryType = (string) ($InfoFieldList[5] ?? ''); + if (is_numeric($categoryType)) { // deprecated: must use the category code instead of id. For backward compatibility. + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $categoryType = self::MAP_ID_TO_CODE[(int) $categoryType] ?? ''; + } + $categoryRoots = (string) ($InfoFieldList[6] ?? ''); + $sortField = (string) ($InfoFieldList[7] ?? ''); + + return array( + 'all' => $all, + 'tableName' => $tableName, + 'labelFullFields' => $labelFullFields, + 'labelFields' => $labelFields, + 'labelAlias' => $labelAlias, + 'keyField' => $keyField, + 'parentName' => $parentName, + 'parentFullField' => $parentFullField, + 'parentField' => $parentField, + 'parentAlias' => $parentAlias, + 'filter' => $filter, + 'categoryType' => $categoryType, + 'categoryRoots' => $categoryRoots, + 'sortField' => $sortField, + ); + } + + /** + * Get sql info of the full field + * + * @param string $fullField Full field (ex: p.test AS label or f(a,b,c) AS label) + * @return array{field:string,alias:string} + */ + public function getSqlFieldInfo($fullField) + { + if (preg_match('/(.*)\s+AS\s+(\w+)$/i', $fullField, $matches)) { + $field = $matches[1]; + $alias = $matches[2]; + } else { + $field = $fullField; + $alias = $fullField; + } + + if (preg_match('/^\w+\.(.*)/i', $field, $matches)) { + $alias = $matches[1]; + } + + return array( + 'field' => $field, + 'alias' => $alias, + ); + } + + /** + * Get list of options + * + * @param FieldInfos $fieldInfos Array of properties for field to show + * @param string $key Key of field + * @param bool $addEmptyValue Add also empty value if needed + * @param bool $reload Force reload options + * @param string|array $selectedValues Only selected values + * @return array|null Return null if error + */ + public function getOptions($fieldInfos, $key, $addEmptyValue = false, $reload = false, $selectedValues = array()) + { + global $conf, $langs; + + $selectedValues = array_map('trim', is_array($selectedValues) ? $selectedValues : array($selectedValues)); + + if (!isset(self::$options[$key]) || $reload) { + $options = array(); + if (!empty($fieldInfos->options) && is_array($fieldInfos->options)) { + $optionsParams = $this->getOptionsParams($fieldInfos->options); + + if ($optionsParams['tableName'] == 'categorie' && !empty($optionsParams['categoryType'])) { + $data = self::$form->select_all_categories($optionsParams['categoryType'], '', 'parent', 64, $optionsParams['categoryRoots'], 1, 1); + if (is_array($data)) { + foreach ($data as $data_key => $data_value) { + $options[$data_key] = array( + 'label' => $data_value, + 'parent' => '', + ); + } + } + } else { + $filter = $optionsParams['filter']; + $hasExtra = !empty($filter) && strpos($filter, 'extra.') !== false; + $keyField = ($hasExtra ? 'main.' : '') . $optionsParams['keyField']; + + $keyList = $keyField . ' AS rowid'; + if (!empty($optionsParams['parentFullField'])) { + $keyList .= ', ' . $optionsParams['parentFullField']; + } + if (!empty($optionsParams['labelFullFields'])) { + $keyList .= ', ' . implode(', ', $optionsParams['labelFullFields']); + } + + $sql = "SELECT " . $keyList; + $sql .= " FROM " . $this->db->sanitize($this->db->prefix() . $optionsParams['tableName']); + if ($hasExtra) { + $sql .= " AS main"; + $sql .= " LEFT JOIN " . $this->db->sanitize($this->db->prefix() . $optionsParams['tableName']) . "_extrafields AS extra ON extra.fk_object = " . $keyField; + } + + // Add filter from 4th field + if (!empty($filter)) { + // can use current entity filter + if (strpos($filter, '$ENTITY$') !== false) { + $filter = str_replace('$ENTITY$', (string) $conf->entity, $filter); + } + // can use SELECT request + if (strpos($filter, '$SEL$') !== false && !getDolGlobalString("MAIN_DISALLOW_UNSECURED_SELECT_INTO_EXTRAFIELDS_FILTER")) { + $filter = str_replace('$SEL$', 'SELECT', $filter); + } + // can use MODE parameter (list or view) + if (strpos($filter, '$MODE$') !== false) { + $filter = str_replace('$MODE$', empty($fieldInfos->mode) ? 'view' : $fieldInfos->mode, $filter); + } + + // Current object id can be used into filter + $objectid = isset($fieldInfos->otherParams['objectId']) ? (int) $fieldInfos->otherParams['objectId'] : (isset($fieldInfos->object) && is_object($fieldInfos->object) ? (int) $fieldInfos->object->id : 0); + if (strpos($filter, '$ID$') !== false && !empty($objectid)) { + $filter = str_replace('$ID$', (string) $objectid, $filter); + } elseif (substr($_SERVER["PHP_SELF"], -8) == 'list.php') { + // In filters of list views, we do not want $ID$ replaced by 0. So we remove the '=' condition. + // Do nothing if condition is using 'IN' keyword + // Replace 'column = $ID$' by "word" + $filter = preg_replace('#\b([a-zA-Z0-9-\.-_]+)\b *= *\$ID\$#', '$1', $filter); + // Replace '$ID$ = column' by "word" + $filter = preg_replace('#\$ID\$ *= *\b([a-zA-Z0-9-\.-_]+)\b#', '$1', $filter); + } else { + $filter = str_replace('$ID$', '0', $filter); + } + + // can use filter on any field of object + if (isset($fieldInfos->object) && is_object($fieldInfos->object)) { + $object = $fieldInfos->object; + $tags = []; + preg_match_all('/\$(.*?)\$/', $filter, $tags); // Example: $filter is ($dateadh$:<=:CURRENT_DATE) + foreach ($tags[0] as $keytag => $valuetag) { + $property = preg_replace('/[^a-z0-9_]/', '', strtolower($tags[1][$keytag])); + if (strpos($filter, $valuetag) !== false && property_exists($object, $property) && !empty($object->$property)) { + $filter = str_replace($valuetag, (string) $object->$property, $filter); + } else { + $filter = str_replace($valuetag, '0', $filter); + } + } + } + + $errstr = ''; + $sql .= " WHERE " . forgeSQLFromUniversalSearchCriteria($filter, $errstr, 1); + } else { + $sql .= ' WHERE 1=1'; + } + // Some tables may have field, some other not. For the moment we disable it. + if (in_array($optionsParams['tableName'], array('tablewithentity'))) { + $sql .= " AND entity = " . ((int) $conf->entity); + } + // Manage dependency list (from AJAX) + if (isset($fieldInfos->optionsSqlDependencyValue)) { + // TODO rework for dependency with a date or a multiselect + $sql .= " AND " . $optionsParams['parentField'] . " = '" . $this->db->escape($fieldInfos->optionsSqlDependencyValue) . "'"; + } + // Only selected values + if (!empty($selectedValues)) { + $tmp = "'" . implode("','", array_map(array($this->db, 'escape'), $selectedValues)) . "'"; + $sql .= " AND " . $keyField . " IN (" . $this->db->sanitize($tmp, 1) . ")"; + } + + // Note: $InfoFieldList can be 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:CategoryIdType[:CategoryIdList[:Sortfield]]]]]]' + if (preg_match('/^[a-z0-9_\-,]+$/i', $optionsParams['sortField'])) { + $sql .= $this->db->order($optionsParams['sortField']); + } else { + $sql .= $this->db->order(implode(', ', $optionsParams['labelFields'])); + } + + $limit = getDolGlobalInt('MAIN_EXTRAFIELDS_LIMIT_SELLIST_SQL', $fieldInfos->optionsSqlLimit ?? 1000); + $offset = $fieldInfos->optionsSqlOffset ?? (isset($fieldInfos->optionsSqlPage) ? (((int) $fieldInfos->optionsSqlPage) - 1) * $limit : 0); + $sql .= $this->db->plimit($limit, $offset); + + dol_syslog(get_class($this) . '::getOptions', LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) { + while ($obj = $this->db->fetch_object($resql)) { + $optionKey = (string) $obj->rowid; + + $toPrint = array(); + foreach ($optionsParams['labelAlias'] as $fieldToShow) { + $toPrint[] = is_string($obj->$fieldToShow) ? $langs->trans($obj->$fieldToShow) : $obj->$fieldToShow; + } + $optionLabel = implode(' ', $toPrint); + + if (empty($optionLabel)) { + $optionLabel = '(not defined)'; + } + + // Manage dependency list + $fieldValueParent = !empty($optionsParams['parentName']) && !empty($optionsParams['parentAlias']) ? $optionsParams['parentName'] . ':' . ((string) $obj->{$optionsParams['parentAlias']}) : ''; + + $options[$optionKey] = array( + 'id' => $optionKey, + 'label' => $optionLabel, + 'parent' => $fieldValueParent, + ); + } + $this->db->free($resql); + } else { + $this->error = 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.
    '; + return null; + } + } + } + if ($addEmptyValue && (!$fieldInfos->required || count($options) > 1)) { + // For preserve the numeric key indexes + $options = array( + '' => array( + 'id' => '', + 'label' => ' ', + 'parent' => '', + ) + ) + $options; + } + + self::$options[$key] = $options; + } + + $options = self::$options[$key]; + // Only selected values + if (!empty($selectedValues)) { + $options = array_intersect_key($options, array_flip($selectedValues)); + } + + return $options; + } +} diff --git a/htdocs/core/class/fields/datefield.class.php b/htdocs/core/class/fields/datefield.class.php new file mode 100644 index 00000000000..191f923c30e --- /dev/null +++ b/htdocs/core/class/fields/datefield.class.php @@ -0,0 +1,261 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/datefield.class.php + * \ingroup core + * \brief File of class to date field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to date field + */ +class DateField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $langs; + + // TODO Must also support $moreCss ? + + $htmlName = $keyPrefix . $key . $keySuffix; + $prefill = array( + 'start' => $value['start'] ?? '', + 'end' => $value['end'] ?? '', + ); + + // Search filter on a date field shows two inputs to select a date range + $out = '
    '; + $out .= self::$form->selectDate($prefill['start'], $htmlName . '_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + $out .= '
    '; + $out .= self::$form->selectDate($prefill['end'], $htmlName . '_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); + $out .= '
    '; + + return $out; + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $required = $fieldInfos->required ? 1 : 0; + $htmlName = $keyPrefix . $key . $keySuffix; + + // Do not show current date when field not required (see selectDate() method) + if (!$required && $this->isEmptyValue($fieldInfos, $value)) { + $value = '-1'; + } + + // TODO Must also support $moreAttrib and $moreCss ? + return self::$form->selectDate($value, $htmlName, 0, 0, $required, '', 1, 1, 0, 1); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + // We suppose dates without time are always gmt (storage of course + output) + return !$this->isEmptyValue($fieldInfos, $value) ? dol_print_date($value, 'day') : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'minwidth100imp'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isTimestamp($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName . 'month') || GETPOSTISSET($htmlName . 'day') || GETPOSTISSET($htmlName . 'year')) { + $value = dol_mktime(12, 0, 0, GETPOSTINT($htmlName . 'month'), GETPOSTINT($htmlName . 'day'), GETPOSTINT($htmlName . 'year')); // for date without hour, we use gmt + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName . '_startmonth') || GETPOSTISSET($htmlName . '_startday') || GETPOSTISSET($htmlName . '_startyear')) { + $start = dol_mktime(0, 0, 0, GETPOSTINT($htmlName . '_startmonth'), GETPOSTINT($htmlName . '_startday'), GETPOSTINT($htmlName . '_startyear')); + } else { + $start = is_array($defaultValue) && isset($defaultValue['start']) ? $defaultValue['start'] : ''; + } + + if (GETPOSTISSET($htmlName . '_endmonth') || GETPOSTISSET($htmlName . '_endday') || GETPOSTISSET($htmlName . '_endyear')) { + $end = dol_mktime(23, 59, 59, GETPOSTINT($htmlName . '_endmonth'), GETPOSTINT($htmlName . '_endday'), GETPOSTINT($htmlName . '_endyear')); + } else { + $end = is_array($defaultValue) && isset($defaultValue['end']) ? $defaultValue['end'] : ''; + } + + return array( + 'start' => $start, + 'end' => $end, + ); + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + $field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key)); + $sql = ''; + + if (is_array($value)) { + $hasStart = !is_null($value['start']) && $value['start'] !== ''; + $hasEnd = !is_null($value['start']) && $value['start'] !== ''; + if ($hasStart && $hasEnd) { + $sql = " AND (" . $field . " BETWEEN '" . $this->db->idate($value['start']) . "' AND '" . $this->db->idate($value['end']) . "')"; + } elseif ($hasStart) { + $sql = " AND " . $field . " >= '" . $this->db->idate($value['start']) . "'"; + } elseif ($hasEnd) { + $sql = " AND " . $field . " <= '" . $this->db->idate($value['end']) . "'"; + } + } elseif (is_numeric($value)) { + include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; + $value = dol_get_first_hour($value); + $sql = " AND " . $field . " = '" . $this->db->idate($value) . "'"; + } + + return $sql; + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/datetimefield.class.php b/htdocs/core/class/fields/datetimefield.class.php new file mode 100644 index 00000000000..6e29a76fb7a --- /dev/null +++ b/htdocs/core/class/fields/datetimefield.class.php @@ -0,0 +1,258 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/datetimefield.class.php + * \ingroup core + * \brief File of class to datetime field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to datetime field + */ +class DatetimeField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $langs; + + // TODO Must also support $moreCss ? + + $htmlName = $keyPrefix . $key . $keySuffix; + $prefill = array( + 'start' => $value['start'] ?? '', + 'end' => $value['end'] ?? '', + ); + + // Search filter on a date field shows two inputs to select a date range + $out = '
    '; + $out .= self::$form->selectDate($prefill['start'], $htmlName . '_start', 1, 1, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"), 'tzuserrel'); + $out .= '
    '; + $out .= self::$form->selectDate($prefill['end'], $htmlName . '_end', 1, 1, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"), 'tzuserrel'); + $out .= '
    '; + + return $out; + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $required = $fieldInfos->required ? 1 : 0; + $htmlName = $keyPrefix . $key . $keySuffix; + + // Do not show current date when field not required (see selectDate() method) + if (!$required && $this->isEmptyValue($fieldInfos, $value)) { + $value = '-1'; + } + + // TODO Must also support $moreAttrib and $moreCss ? + return self::$form->selectDate($value, $htmlName, 1, 1, $required, '', 1, 1, 0, 1, '', '', '', 1, '', '', 'tzuserrel'); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? dol_print_date($value, 'dayhour', 'tzuserrel') : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'minwidth200imp'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isTimestamp($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName . 'hour') || GETPOSTISSET($htmlName . 'min') || GETPOSTISSET($htmlName . 'sec') || GETPOSTISSET($htmlName . 'month') || GETPOSTISSET($htmlName . 'day') || GETPOSTISSET($htmlName . 'year')) { + $value = dol_mktime(GETPOSTINT($htmlName . 'hour'), GETPOSTINT($htmlName . 'min'), GETPOSTINT($htmlName . 'sec'), GETPOSTINT($htmlName . 'month'), GETPOSTINT($htmlName . 'day'), GETPOSTINT($htmlName . 'year'), 'tzuserrel'); // for date without hour, we use gmt + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName . '_startmonth') || GETPOSTISSET($htmlName . '_startday') || GETPOSTISSET($htmlName . '_startyear')) { + $start = dol_mktime(0, 0, 0, GETPOSTINT($htmlName . '_startmonth'), GETPOSTINT($htmlName . '_startday'), GETPOSTINT($htmlName . '_startyear'), 'tzuserrel'); + } else { + $start = is_array($defaultValue) && isset($defaultValue['start']) ? $defaultValue['start'] : ''; + } + + if (GETPOSTISSET($htmlName . '_endmonth') || GETPOSTISSET($htmlName . '_endday') || GETPOSTISSET($htmlName . '_endyear')) { + $end = dol_mktime(23, 59, 59, GETPOSTINT($htmlName . '_endmonth'), GETPOSTINT($htmlName . '_endday'), GETPOSTINT($htmlName . '_endyear'), 'tzuserrel'); + } else { + $end = is_array($defaultValue) && isset($defaultValue['end']) ? $defaultValue['end'] : ''; + } + + return array( + 'start' => $start, + 'end' => $end, + ); + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + $field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key)); + $sql = ''; + + if (is_array($value)) { + $hasStart = !is_null($value['start']) && $value['start'] !== ''; + $hasEnd = !is_null($value['start']) && $value['start'] !== ''; + if ($hasStart && $hasEnd) { + $sql = " AND (" . $field . " BETWEEN '" . $this->db->idate($value['start']) . "' AND '" . $this->db->idate($value['end']) . "')"; + } elseif ($hasStart) { + $sql = " AND " . $field . " >= '" . $this->db->idate($value['start']) . "'"; + } elseif ($hasEnd) { + $sql = " AND " . $field . " <= '" . $this->db->idate($value['end']) . "'"; + } + } elseif (is_numeric($value)) { + $sql = " AND " . $field . " = '" . $this->db->idate($value) . "'"; + } + + return $sql; + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/datetimegmtfield.class.php b/htdocs/core/class/fields/datetimegmtfield.class.php new file mode 100644 index 00000000000..445b92d4349 --- /dev/null +++ b/htdocs/core/class/fields/datetimegmtfield.class.php @@ -0,0 +1,258 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/datetimegmtfield.class.php + * \ingroup core + * \brief File of class to datetimegmt field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to datetimegmt field + */ +class DatetimegmtField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $langs; + + // TODO Must also support $moreCss ? + + $htmlName = $keyPrefix . $key . $keySuffix; + $prefill = array( + 'start' => $value['start'] ?? '', + 'end' => $value['end'] ?? '', + ); + + // Search filter on a date field shows two inputs to select a date range + $out = '
    '; + $out .= self::$form->selectDate($prefill['start'], $htmlName . '_start', 1, 1, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"), 'gmt'); + $out .= '
    '; + $out .= self::$form->selectDate($prefill['end'], $htmlName . '_end', 1, 1, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"), 'gmt'); + $out .= '
    '; + + return $out; + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $required = $fieldInfos->required ? 1 : 0; + $htmlName = $keyPrefix . $key . $keySuffix; + + // Do not show current date when field not required (see selectDate() method) + if (!$required && $this->isEmptyValue($fieldInfos, $value)) { + $value = '-1'; + } + + // TODO Must also support $moreAttrib and $moreCss ? + return self::$form->selectDate($value, $htmlName, 1, 1, $required, '', 1, 1, 0, 1, '', '', '', 1, '', '', 'gmt'); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? dol_print_date($value, 'dayhour', 'gmt') : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'minwidth200imp'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isTimestamp($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName . 'hour') || GETPOSTISSET($htmlName . 'min') || GETPOSTISSET($htmlName . 'sec') || GETPOSTISSET($htmlName . 'month') || GETPOSTISSET($htmlName . 'day') || GETPOSTISSET($htmlName . 'year')) { + $value = dol_mktime(GETPOSTINT($htmlName . 'hour'), GETPOSTINT($htmlName . 'min'), GETPOSTINT($htmlName . 'sec'), GETPOSTINT($htmlName . 'month'), GETPOSTINT($htmlName . 'day'), GETPOSTINT($htmlName . 'year'), 'gmt'); // for date without hour, we use gmt + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName . '_startmonth') || GETPOSTISSET($htmlName . '_startday') || GETPOSTISSET($htmlName . '_startyear')) { + $start = dol_mktime(0, 0, 0, GETPOSTINT($htmlName . '_startmonth'), GETPOSTINT($htmlName . '_startday'), GETPOSTINT($htmlName . '_startyear'), 'gmt'); + } else { + $start = is_array($defaultValue) && isset($defaultValue['start']) ? $defaultValue['start'] : ''; + } + + if (GETPOSTISSET($htmlName . '_endmonth') || GETPOSTISSET($htmlName . '_endday') || GETPOSTISSET($htmlName . '_endyear')) { + $end = dol_mktime(23, 59, 59, GETPOSTINT($htmlName . '_endmonth'), GETPOSTINT($htmlName . '_endday'), GETPOSTINT($htmlName . '_endyear'), 'gmt'); + } else { + $end = is_array($defaultValue) && isset($defaultValue['end']) ? $defaultValue['end'] : ''; + } + + return array( + 'start' => $start, + 'end' => $end, + ); + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + $field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key)); + $sql = ''; + + if (is_array($value)) { + $hasStart = !is_null($value['start']) && $value['start'] !== ''; + $hasEnd = !is_null($value['start']) && $value['start'] !== ''; + if ($hasStart && $hasEnd) { + $sql = " AND (" . $field . " BETWEEN '" . $this->db->idate($value['start']) . "' AND '" . $this->db->idate($value['end']) . "')"; + } elseif ($hasStart) { + $sql = " AND " . $field . " >= '" . $this->db->idate($value['start']) . "'"; + } elseif ($hasEnd) { + $sql = " AND " . $field . " <= '" . $this->db->idate($value['end']) . "'"; + } + } elseif (is_numeric($value)) { + $sql = " AND " . $field . " = '" . $this->db->idate($value) . "'"; + } + + return $sql; + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/doublefield.class.php b/htdocs/core/class/fields/doublefield.class.php new file mode 100644 index 00000000000..c1a80ee2414 --- /dev/null +++ b/htdocs/core/class/fields/doublefield.class.php @@ -0,0 +1,220 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/doublefield.class.php + * \ingroup core + * \brief File of class to double field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to double field + */ +class DoubleField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, $value, $htmlName, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $value = !$this->isEmptyValue($fieldInfos, $value) ? price((double) $value) : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, $value, $htmlName, $moreCss, $moreAttrib . $autoFocus); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? price((double) $value) : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'maxwidth75'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isNumeric($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + $value = GETPOST($htmlName, 'restricthtml'); + $value = str_replace(',', '.', $value); + + return $this->verifyFieldValue($fieldInfos, $key, $value); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = (double) price2num(GETPOST($htmlName, 'alphanohtml')); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 1); + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/durationfield.class.php b/htdocs/core/class/fields/durationfield.class.php new file mode 100644 index 00000000000..3ccc6235ff5 --- /dev/null +++ b/htdocs/core/class/fields/durationfield.class.php @@ -0,0 +1,207 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/durationfield.class.php + * \ingroup core + * \brief File of class to duration field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; + + +/** + * Class to duration field + */ +class DurationField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + // Todo make filter with min / max ? or same as a number ? + return $this->printInputField($fieldInfos, $key, $value, $keyPrefix, $keySuffix, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + // TODO Must also support $moreAttrib and $moreCss ? + return self::$form->select_duration($htmlName, (int) $value, 0, 'text', 0, 1); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? convertSecondToTime((int) $value, 'allhourmin') : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isDuration($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName . 'hour') || GETPOSTISSET($htmlName . 'min')) { + $value_hours = GETPOSTINT($htmlName . "hour"); + $value_minutes = GETPOSTINT($htmlName . "min"); + $value = $value_hours * 3600 + $value_minutes * 60; + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + return $this->getPostFieldValue($fieldInfos, $key, $defaultValue, $keyPrefix, $keySuffix); + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 0); + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/emailfield.class.php b/htdocs/core/class/fields/emailfield.class.php new file mode 100644 index 00000000000..f2b73df8461 --- /dev/null +++ b/htdocs/core/class/fields/emailfield.class.php @@ -0,0 +1,217 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/emailfield.class.php + * \ingroup core + * \brief File of class to email field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to email field + */ +class EmailField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, $value, $htmlName, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib . $autoFocus); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? dol_print_email((string) $value, 0, 0, 0, 64, 1, 1) : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isEmail($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alphanohtml'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 0); + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/htmlfield.class.php b/htdocs/core/class/fields/htmlfield.class.php new file mode 100644 index 00000000000..58095d9f529 --- /dev/null +++ b/htdocs/core/class/fields/htmlfield.class.php @@ -0,0 +1,217 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/htmlfield.class.php + * \ingroup core + * \brief File of class to html field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +// TODO same as text field ? + +/** + * Class to html field + */ +class HtmlField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, $value, $htmlName, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputHtml($htmlName, $value, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + if (!empty($fieldInfos->options)) { + $value = str_replace(',', "\n", (string) $value); + } + + return dol_htmlentitiesbr((string) $value); + } + + return ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + return parent::verifyFieldValue($fieldInfos, $key, $value); + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, empty($fieldInfos->getPostCheck) ? 'restricthtml' : $fieldInfos->getPostCheck); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 0); + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/iconfield.class.php b/htdocs/core/class/fields/iconfield.class.php new file mode 100644 index 00000000000..8d1c9b9d8ed --- /dev/null +++ b/htdocs/core/class/fields/iconfield.class.php @@ -0,0 +1,211 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/iconfield.class.php + * \ingroup core + * \brief File of class to icon field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to icon field + */ +class IconField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $placeHolder = $fieldInfos->inputPlaceholder; + if (!empty($placeHolder)) $placeHolder = ' placeholder="' . dolPrintHTMLForAttribute($placeHolder) . '"'; + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputIcon($htmlName, (string) $value, $moreCss, $moreAttrib . $placeHolder . $autoFocus); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? self::$form->outputIcon((string) $value) : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + return parent::verifyFieldValue($fieldInfos, $key, $value); + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $check = $key == 'lang' ? 'aZ09' : 'alphanohtml'; + $value = GETPOST($htmlName, $check); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 0); + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/intfield.class.php b/htdocs/core/class/fields/intfield.class.php new file mode 100644 index 00000000000..605edd47ce9 --- /dev/null +++ b/htdocs/core/class/fields/intfield.class.php @@ -0,0 +1,218 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/intfield.class.php + * \ingroup core + * \brief File of class to int field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to int field + */ +class IntField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $size = (int) $fieldInfos->size; + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $maxLength = ''; // $size > 0 ? ' maxlength="' . $size . '"' : ''; // TODO rework, wrong method + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + $value = !is_null($value) && $value !== '' ? (int) $value : ''; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $maxLength . $moreAttrib . $autoFocus); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? (string) $value : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'maxwidth75'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isNumeric($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = (int) price2num(GETPOSTINT($htmlName)); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 1); + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/ipfield.class.php b/htdocs/core/class/fields/ipfield.class.php new file mode 100644 index 00000000000..9484705a0c4 --- /dev/null +++ b/htdocs/core/class/fields/ipfield.class.php @@ -0,0 +1,222 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/ipfield.class.php + * \ingroup core + * \brief File of class to ip field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to ip field + */ +class IpField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib . $autoFocus); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? dol_print_ip((string) $value, 0) : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + global $langs; + + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + // TODO move to class Validate + if (!filter_var($value, FILTER_VALIDATE_IP)) { + self::$validator->error = $langs->trans('RequireValidValue'); + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alphanohtml'); + } else { + $value = $defaultValue; + } + + return $value; + } + + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 0); + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/linestrgfield.class.php b/htdocs/core/class/fields/linestrgfield.class.php new file mode 100644 index 00000000000..8bab9b03677 --- /dev/null +++ b/htdocs/core/class/fields/linestrgfield.class.php @@ -0,0 +1,32 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/linestrgfield.class.php + * \ingroup core + * \brief File of class to linestrg field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commongeofield.class.php'; + + +/** + * Class to linestrg field + */ +class LinestrgField extends CommonGeoField +{ +} diff --git a/htdocs/core/class/fields/linkfield.class.php b/htdocs/core/class/fields/linkfield.class.php new file mode 100644 index 00000000000..caaa372c172 --- /dev/null +++ b/htdocs/core/class/fields/linkfield.class.php @@ -0,0 +1,437 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/linkfield.class.php + * \ingroup core + * \brief File of class to link field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to link field + */ +class LinkField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array('', '-1', '0', 0); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + $optionParams = $this->getOptionsParams($fieldInfos->options); + + if (version_compare(DOL_VERSION, '19.0.0') < 0) { + // Example: 'ObjectName:classPath:1:(status:=:1)' + $objectDesc = $optionParams['all']; + if (strpos($objectDesc, '$ID$') !== false && !empty($fieldInfos->object->id)) { + $objectDesc = str_replace('$ID$', (string) $fieldInfos->object->id, $objectDesc); + } + + $out = self::$form->selectForForms($objectDesc, $htmlName, (int) $value, 0, '', '', $moreCss, $moreAttrib); + } else { + // 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. + $objectDesc = $optionParams['objectClass'] . ':' . $optionParams['pathToClass']; + + // Example: 'actioncomm:options_fff' To be used in priority to know object linked with all its definition (including filters) + // 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 + // 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. + $objectField = isset($fieldInfos->object) ? $fieldInfos->object->element . (!empty($fieldInfos->object->module) ? '@' . $fieldInfos->object->module : '') . ':' . ($fieldInfos->fieldType == FieldInfos::FIELD_TYPE_EXTRA_FIELD ? 'options_' : '') . $fieldInfos->nameInClass : ''; + + $out = self::$form->selectForForms($objectDesc, $htmlName, (int) $value, 0, '', '', $moreCss, $moreAttrib, 0, 0, '', $objectField); + } + + return $out; + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $langs; + + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $placeHolder = $fieldInfos->inputPlaceholder; + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + $showEmpty = $fieldInfos->required && !$this->isEmptyValue($fieldInfos, $fieldInfos->defaultValue) ? 0 : 1; + + $optionParams = $this->getOptionsParams($fieldInfos->options); + + // If we have to add a create button + if ($optionParams['addCreateButton']) { + if (!empty($fieldInfos->picto)) { + $moreCss .= ' widthcentpercentminusxx'; + } else { + $moreCss .= ' widthcentpercentminusx'; + } + } elseif (!empty($fieldInfos->picto)) { + $moreCss .= ' widthcentpercentminusx'; + } + + if (version_compare(DOL_VERSION, '19.0.0') < 0) { + // Example: 'ObjectName:classPath:1:(status:=:1)' + $objectDesc = $optionParams['all']; + if (strpos($objectDesc, '$ID$') !== false && !empty($fieldInfos->object->id)) { + $objectDesc = str_replace('$ID$', (string) $fieldInfos->object->id, $objectDesc); + } + + $out = self::$form->selectForForms($objectDesc, $htmlName, (int) $value, $showEmpty, '', $placeHolder, $moreCss, $moreAttrib . $autoFocus, 0, $fieldInfos->inputDisabled ? 1 : 0); + } else { + // 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. + $objectDesc = $optionParams['objectClass'] . ':' . $optionParams['pathToClass']; + + // Example: 'actioncomm:options_fff' To be used in priority to know object linked with all its definition (including filters) + // 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 + // 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. + $objectField = isset($fieldInfos->object) ? $fieldInfos->object->element . (!empty($fieldInfos->object->module) ? '@' . $fieldInfos->object->module : '') . ':' . ($fieldInfos->fieldType == FieldInfos::FIELD_TYPE_EXTRA_FIELD ? 'options_' : '') . $fieldInfos->nameInClass : ''; + + $out = self::$form->selectForForms($objectDesc, $htmlName, (int) $value, $showEmpty, '', $placeHolder, $moreCss, $moreAttrib . $autoFocus, 0, $fieldInfos->inputDisabled ? 1 : 0, '', $objectField); + } + + if ($optionParams['addCreateButton'] && // If we have to add a create button + (!GETPOSTISSET('backtopage') || strpos(GETPOST('backtopage'), $_SERVER['PHP_SELF']) === 0) && // To avoid to open several times the 'Plus' button (we accept only one level) + !$fieldInfos->inputDisabled && // To avoid to show the button if the field is protected by a "disabled". + empty($fieldInfos->otherParams['nonewbutton']) // manually disable new button + ) { + $class = $optionParams['objectClass']; + $classfile = $optionParams['pathToClass']; + $classpath = dirname(dirname($classfile)); + if (file_exists(dol_buildpath($classpath . '/card.php'))) { + $url_path = dol_buildpath($classpath . '/card.php', 1); + } else { + $url_path = dol_buildpath($classpath . '/' . strtolower($class) . '_card.php', 1); + } + $paramforthenewlink = ''; + $paramforthenewlink .= (GETPOSTISSET('action') ? '&action=' . GETPOST('action', 'aZ09') : ''); + $paramforthenewlink .= (GETPOSTISSET('id') ? '&id=' . GETPOSTINT('id') : ''); + $paramforthenewlink .= (GETPOSTISSET('origin') ? '&origin=' . GETPOST('origin', 'aZ09') : ''); + $paramforthenewlink .= (GETPOSTISSET('originid') ? '&originid=' . GETPOSTINT('originid') : ''); + $paramforthenewlink .= '&fk_' . strtolower($class) . '=--IDFORBACKTOPAGE--'; + // TODO Add JavaScript code to add input fields already filled into $paramforthenewlink so we won't loose them when going back to main page + $out .= ''; + } + + return $out; + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $optionParams = $this->getOptionsParams($fieldInfos->options); + + $classpath = $optionParams['pathToClass']; + if (!empty($classpath)) { + $classname = $optionParams['objectClass']; + + $object = $this->getObject($classname, $classpath); + if (isset($object)) { + '@phan-var-force CommonObject $object'; + if ($object->element === 'product') { // Special case for product because default valut of fetch are wrong + '@phan-var-force Product $object'; + $result = $object->fetch((int) $value, '', '', '', 0, 1, 1); + } else { + $result = $object->fetch($value); + } + if ($result > 0) { + $getNomUrlParam1 = $optionParams['getNomUrlParam1']; + $getNomUrlParam2 = $optionParams['getNomUrlParam2']; + + if ($object->element === 'product') { + '@phan-var-force Product $object'; + $get_name_url_param_arr = array($getNomUrlParam1, $getNomUrlParam2, 0, -1, 0, '', 0, ' - '); + if (isset($fieldInfos->getNameUrlParams)) { + $get_name_url_params = explode(':', $fieldInfos->getNameUrlParams); + if (!empty($get_name_url_params)) { + $param_num_max = count($get_name_url_param_arr) - 1; + foreach ($get_name_url_params as $param_num => $param_value) { + if ($param_num > $param_num_max) { + break; + } + $get_name_url_param_arr[$param_num] = $param_value; + } + } + } + + /** + * @var Product $object + */ + return self::$form->getNomUrl($object, (int) $get_name_url_param_arr[0], $get_name_url_param_arr[1], (int) $get_name_url_param_arr[2], (int) $get_name_url_param_arr[3], (int) $get_name_url_param_arr[4], $get_name_url_param_arr[5], (int) $get_name_url_param_arr[6], $get_name_url_param_arr[7]); + } elseif (get_class($object) == 'Categorie') { + // For category object, rendering must use the same method than the one deinfed into showCategories() + $color = $object->color; + $sfortag = ''; + $sfortag .= self::$form->getNomUrl($object, (int) $getNomUrlParam1, $getNomUrlParam2); + $sfortag .= ''; + return $sfortag; + } else { + return self::$form->getNomUrl($object, (int) $getNomUrlParam1, $getNomUrlParam2); + } + } + } else { + dol_syslog('Error bad setup of field : ' . $key, LOG_WARNING); + return 'Error bad setup of field'; + } + } else { + dol_syslog('Error bad setup of field : ' . $key, LOG_WARNING); + return 'Error bad setup of field'; + } + } + + return ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'minwidth200imp'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + $optionParams = $this->getOptionsParams($fieldInfos->options); + $classname = $optionParams['objectClass']; + $classpath = $optionParams['pathToClass']; + $object = $this->getObject($classname, $classpath); + if (isset($object) && method_exists($object, 'isExistingObject') && !self::$validator->isFetchable((int) $value, $classname, $classpath) // All class don't have isExistingObject function ... + && (version_compare(DOL_VERSION, '19.0.0') < 0 || !self::$validator->isFetchableElement((int) $value, $classname)) // from V19 of Dolibarr, In some cases link use element instead of class, example project_task + ) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOSTINT($htmlName); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alphanohtml'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 2); + } + + return ''; + } + + /** + * Get all parameters in the options + * + * @param array $options Options of the field + * @return array{all:string,objectClass:string,pathToClass:string,addCreateButton:bool,getNomUrlParam1:string,getNomUrlParam2:string,filter:string,sortField:string} + */ + public function getOptionsParams($options) + { + $options = is_array($options) ? $options : array(); + $paramList = array_keys($options); + // Example: $paramList[0] = 'ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]' + // Example: $paramList[0] = 'ObjectClass:PathToClass:#getnomurlparam1=-1#getnomurlparam2=customer' + // Example: $paramList[0] = 'ObjectName:classPath' but can also be 'ObjectName:classPath:1:(status:=:1)' + + $all = (string) $paramList[0]; + $InfoFieldList = explode(":", $all); + + $objectClass = (string) ($InfoFieldList[0] ?? ''); + $pathToClass = (string) ($InfoFieldList[1] ?? ''); + $addCreateButton = !empty($InfoFieldList[2]) && is_numeric($InfoFieldList[2]); + $getNomUrlParam1 = 3; + $getNomUrlParam2 = ''; + if (preg_match('/#getnomurlparam1=([^#:]*)/', $all, $matches)) { + $getNomUrlParam1 = $matches[1]; + } + if (preg_match('/#getnomurlparam2=([^#:]*)/', $all, $matches)) { + $getNomUrlParam2 = $matches[1]; + } + $filter = (string) ($InfoFieldList[3] ?? ''); + $sortField = (string) ($InfoFieldList[4] ?? ''); + + return array( + 'all' => $all, + 'objectClass' => $objectClass, + 'pathToClass' => $pathToClass, + 'addCreateButton' => $addCreateButton, + 'getNomUrlParam1' => $getNomUrlParam1, + 'getNomUrlParam2' => $getNomUrlParam2, + 'filter' => $filter, + 'sortField' => $sortField, + ); + } + + /** + * Get object handler + * + * @param string $objectClass Class name + * @param string $pathToClass Path to the class + * @return CommonObject|null + */ + public function getObject($objectClass, $pathToClass) + { + dol_include_once($pathToClass); + if ($objectClass && !class_exists($objectClass)) { + // from V19 of Dolibarr, In some cases link use element instead of class, example project_task + // TODO use newObjectByElement() introduce in V20 by PR #30036 for better errors management + $element_prop = getElementProperties($objectClass); + if ($element_prop) { + $objectClass = $element_prop['classname']; + } + } + + if ($objectClass && class_exists($objectClass)) { + return new $objectClass($this->db); + } + + return null; + } +} diff --git a/htdocs/core/class/fields/multiptsfield.class.php b/htdocs/core/class/fields/multiptsfield.class.php new file mode 100644 index 00000000000..4cceca7da80 --- /dev/null +++ b/htdocs/core/class/fields/multiptsfield.class.php @@ -0,0 +1,32 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/multiptsfield.class.php + * \ingroup core + * \brief File of class to multipts field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commongeofield.class.php'; + + +/** + * Class to multipts field + */ +class MultiptsField extends CommonGeoField +{ +} diff --git a/htdocs/core/class/fields/passwordfield.class.php b/htdocs/core/class/fields/passwordfield.class.php new file mode 100644 index 00000000000..5d555fb01f5 --- /dev/null +++ b/htdocs/core/class/fields/passwordfield.class.php @@ -0,0 +1,249 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/passwordfield.class.php + * \ingroup core + * \brief File of class to password field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to password field + */ +class PasswordField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + + $out = ''; // Hidden field to reduce impact of evil Google Chrome autopopulate bug. + if ($htmlName == 'pass_crypted') { + $out .= self::$form->inputType('password', 'pass', '', 'pass', $moreCss, ' autocomplete="new-password"' . $moreAttrib . $autoFocus); + $out .= self::$form->inputType('hidden', 'pass_crypted', (string) $value, 'pass_crypted', $moreCss, $moreAttrib); + } else { + $out .= self::$form->inputType('password', $htmlName, (string) $value, $htmlName, $moreCss, ' autocomplete="new-password"' . $moreAttrib . $autoFocus); + } + + return $out; + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $langs; + + return !$this->isEmptyValue($fieldInfos, $value) ? '' . $langs->trans("Encrypted") . '' : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'maxwidth100'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + global $conf, $langs, $user; + + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + // Todo do we use other method ? + if (getDolGlobalString('USER_PASSWORD_GENERATED')) { + // Add a check on rules for password syntax using the setup of the password generator + $modGeneratePassClass = 'modGeneratePass' . ucfirst(getDolGlobalString('USER_PASSWORD_GENERATED')); + + include_once DOL_DOCUMENT_ROOT . '/core/modules/security/generate/' . $modGeneratePassClass . '.class.php'; + if (class_exists($modGeneratePassClass)) { + $modGeneratePass = new $modGeneratePassClass($this->db, $conf, $langs, $user); + '@phan-var-force ModeleGenPassword $modGeneratePass'; + + // To check an input user password, we disable the cleaning on ambiguous characters (this is used only for auto-generated password) + $modGeneratePass->WithoutAmbi = 0; + + // Call to validatePassword($password) to check pass match rules + $testpassword = $modGeneratePass->validatePassword($value); + if (!$testpassword) { + self::$validator->error = $langs->trans('RequireValidValue'); + return false; + } + } + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'password'); + } else { + $value = $defaultValue; + } + + return $value; + } + + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + // TODO rework search on crypt password + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 0); + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/phonefield.class.php b/htdocs/core/class/fields/phonefield.class.php new file mode 100644 index 00000000000..a02e6ce6252 --- /dev/null +++ b/htdocs/core/class/fields/phonefield.class.php @@ -0,0 +1,217 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/phonefield.class.php + * \ingroup core + * \brief File of class to phone field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to phone field + */ +class PhoneField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib . $autoFocus); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? dol_print_phone((string) $value, '', 0, 0, '', ' ', 'phone') : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isPhone($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alphanohtml'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 0); + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/pointfield.class.php b/htdocs/core/class/fields/pointfield.class.php new file mode 100644 index 00000000000..cecf6087507 --- /dev/null +++ b/htdocs/core/class/fields/pointfield.class.php @@ -0,0 +1,32 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/pointfield.class.php + * \ingroup core + * \brief File of class to point field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commongeofield.class.php'; + + +/** + * Class to point field + */ +class PointField extends CommonGeoField +{ +} diff --git a/htdocs/core/class/fields/polygonfield.class.php b/htdocs/core/class/fields/polygonfield.class.php new file mode 100644 index 00000000000..dd067293ea6 --- /dev/null +++ b/htdocs/core/class/fields/polygonfield.class.php @@ -0,0 +1,32 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/polygonfield.class.php + * \ingroup core + * \brief File of class to polygon field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commongeofield.class.php'; + + +/** + * Class to polygon field + */ +class PolygonField extends CommonGeoField +{ +} diff --git a/htdocs/core/class/fields/pricecyfield.class.php b/htdocs/core/class/fields/pricecyfield.class.php new file mode 100644 index 00000000000..1e64f20ffff --- /dev/null +++ b/htdocs/core/class/fields/pricecyfield.class.php @@ -0,0 +1,316 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/pricecyfield.class.php + * \ingroup core + * \brief File of class to pricecy field (price with currency) + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to pricecy field (price with currency) + */ +class PricecyField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + $tmp = $this->getPriceAndCurrencyFromValue($fieldInfos, $value); + $value = $tmp['price']; + $currency = $tmp['currency']; + + $tmp = $this->getPriceAndCurrencyAliasAndField($fieldInfos, $key); + $aliasPrice = $tmp['aliasPrice']; + $fieldPrice = $tmp['fieldPrice']; + $aliasCurrency = $tmp['aliasCurrency']; + $fieldCurrency = $tmp['fieldCurrency']; + + $out = self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib); + if (!empty($fieldCurrency)) { + $out .= self::$form->selectCurrency($currency, $htmlName . 'currency_id'); + } + + return $out; + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + $tmp = $this->getPriceAndCurrencyFromValue($fieldInfos, $value); + $value = $tmp['price']; + $currency = $tmp['currency']; + $value = !$this->isEmptyValue($fieldInfos, $value) ? price($value) : ''; + + $out = self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib . $autoFocus); + $out .= self::$form->selectCurrency($currency, $htmlName . 'currency_id'); + + return $out; + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $langs; + $tmp = $this->getPriceAndCurrencyFromValue($fieldInfos, $value); + $value = $tmp['price']; + $currency = $tmp['currency']; + + return !$this->isEmptyValue($fieldInfos, $value) ? price($value, 0, $langs, 0, getDolGlobalInt('MAIN_MAX_DECIMALS_TOT'), -1, $currency) : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'maxwidth75'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + $tmp = $this->getPriceAndCurrencyFromValue($fieldInfos, $value); + $value = $tmp['price']; + $currency = $tmp['currency']; + if (!self::$validator->isNumeric($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + $value = GETPOST($htmlName, 'restricthtml') . ':' . GETPOST($htmlName . "currency_id", 'restricthtml'); + $value = str_replace(',', '.', $value); + + return $this->verifyFieldValue($fieldInfos, $key, $value); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = price2num(GETPOST($htmlName, 'alphanohtml')) . ':' . GETPOST($htmlName . "currency_id", 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = array( + 'value' => GETPOST($htmlName, 'alphanohtml'), + 'currency' => GETPOST($htmlName . "currency_id", 'alpha'), + ); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + $filterValue = $value['value'] ?? ''; + $filterCurrency = $value['currency'] ?? ''; + if ($filterCurrency == '-1') $filterCurrency = ''; + + $tmp = $this->getPriceAndCurrencyAliasAndField($fieldInfos, $key); + $aliasPrice = $tmp['aliasPrice']; + $fieldPrice = $tmp['fieldPrice']; + $aliasCurrency = $tmp['aliasCurrency']; + $fieldCurrency = $tmp['fieldCurrency']; + + if (!empty($filterValue)) { + return natural_search($aliasPrice . $fieldPrice, $filterValue, 1); + } + if (!empty($filterCurrency) && !empty($fieldCurrency)) { + return natural_search($aliasCurrency . $fieldCurrency, $filterCurrency, 0); + } + + return ''; + } + + /** + * Get price and currency from value + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $value Value in memory is a php string like '0.01:EUR' + * @return array{price:double,currency:string} + */ + public function getPriceAndCurrencyFromValue($fieldInfos, $value) + { + global $conf; + + if ($this->isEmptyValue($fieldInfos, $value)) { + $price = ''; + $currency = $conf->currency; + } else { + // $value in memory is a php string like '10.01:USD' + $tmp = explode(':', $value); + $price = $this->isEmptyValue($fieldInfos, $tmp[0] ?? '') ? '' : $tmp[0]; + $currency = !empty($tmp[1]) ? $tmp[1] : $conf->currency; + } + + return array( + 'price' => (double) $price, + 'currency' => $currency + ); + } + + /** + * Get alias and field name in table for price and currency + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @return array{aliasPrice:string,aliasCurrency:string,fieldPrice:string,fieldCurrency:string} + */ + public function getPriceAndCurrencyAliasAndField($fieldInfos, $key) + { + $alias = $fieldInfos->sqlAlias ?? 't.'; + $tmp = explode(':', $alias); + $aliasPrice = $tmp[0] ?? ''; + $aliasCurrency = $tmp[1] ?? ''; + + $field = $fieldInfos->nameInTable ?? $key; + $tmp = explode(':', $field); + $fieldPrice = $tmp[0] ?? ''; + $fieldCurrency = $tmp[1] ?? ''; + + return array( + 'aliasPrice' => trim($aliasPrice), + 'aliasCurrency' => trim($aliasCurrency), + 'fieldPrice' => trim($fieldPrice), + 'fieldCurrency' => trim($fieldCurrency), + ); + } +} diff --git a/htdocs/core/class/fields/pricefield.class.php b/htdocs/core/class/fields/pricefield.class.php new file mode 100644 index 00000000000..8d848b92348 --- /dev/null +++ b/htdocs/core/class/fields/pricefield.class.php @@ -0,0 +1,224 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/pricefield.class.php + * \ingroup core + * \brief File of class to price field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to price field + */ +class PriceField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $conf, $langs; + + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $value = !$this->isEmptyValue($fieldInfos, $value) ? price((double) $value) : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib . $autoFocus) . $langs->getCurrencySymbol($conf->currency); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $conf, $langs; + + return !$this->isEmptyValue($fieldInfos, $value) ? price((double) $value, 0, $langs, 0, 0, -1, $conf->currency) : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'maxwidth75'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isNumeric($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + $value = GETPOST($htmlName, 'restricthtml'); + $value = str_replace(',', '.', $value); + + return $this->verifyFieldValue($fieldInfos, $key, $value); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = (double) price2num(GETPOST($htmlName, 'alphanohtml')); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 1); + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/radiofield.class.php b/htdocs/core/class/fields/radiofield.class.php new file mode 100644 index 00000000000..ca7ee2e7af4 --- /dev/null +++ b/htdocs/core/class/fields/radiofield.class.php @@ -0,0 +1,276 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/radiofield.class.php + * \ingroup core + * \brief File of class to radio field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonselectfield.class.php'; + + +/** + * Class to radio field + */ +class RadioField extends CommonSelectField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $conf; + + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $htmlName = $keyPrefix . $key . $keySuffix; + $value = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value))); + + $optionsList = array(); + $options = $this->getOptions($fieldInfos, $key); + foreach ($options as $optionKey => $optionInfos) { + $options[$optionKey] = $optionInfos['label']; + } + + return self::$form->multiselectarray($htmlName, $optionsList, $value, 0, 0, $moreCss, 0, 0, $moreAttrib, '', '', (int) (!empty($conf->use_javascript_ajax) && !getDolGlobalString('MAIN_EXTRAFIELDS_DISABLE_SELECT2'))); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $htmlName = $keyPrefix . $key . $keySuffix; + + $selectedValue = $this->isEmptyValue($fieldInfos, $value) ? '' : (string) $value; + + $options = $this->getOptions($fieldInfos, $key, true); + $values = array(); + foreach ($options as $optionKey => $optionInfos) { + $values[$optionKey] = $optionInfos['label']; + } + + return self::$form->inputRadio($htmlName, $values, $selectedValue, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $langs; + $value = (string) $value; + + if ($fieldInfos->required && $this->isEmptyValue($fieldInfos, $value)) { + $langs->load('errors'); + $value = '' . $langs->trans('ErrorNoValueForRadioType') . ''; + } else { + $options = $this->getOptions($fieldInfos, $key); + foreach ($options as $optionKey => $optionInfos) { + if (((string) $optionKey) == $value) { + $value = $optionInfos['label']; + break; + } + } + } + + return $value; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'width25'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + global $langs; + $value = (string) $value; + + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + $options = $this->getOptions($fieldInfos, $key); + if (!isset($options[$value])) { + self::$validator->error = $langs->trans('RequireValidValue'); + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + $value = GETPOST($htmlName, 'restricthtml'); + $value = trim($value); + + return $this->verifyFieldValue($fieldInfos, $key, $value); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alphanohtml'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'array'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value) && is_array($value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + $field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key)); + + $tmp = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'"; + return " AND " . $field . " IN (" . $this->db->sanitize($tmp, 1) . ")"; + } + + return ''; + } + + /** + * Get list of options + * + * @param FieldInfos $fieldInfos Array of properties for field to show + * @param string $key Key of field + * @param bool $addEmptyValue Add also empty value if needed + * @param bool $reload Force reload options + * @return array + */ + public function getOptions($fieldInfos, $key, $addEmptyValue = false, $reload = false) + { + return parent::getOptions($fieldInfos, $key, $addEmptyValue, $reload); + } +} diff --git a/htdocs/core/class/fields/realfield.class.php b/htdocs/core/class/fields/realfield.class.php new file mode 100644 index 00000000000..0e3707e31fb --- /dev/null +++ b/htdocs/core/class/fields/realfield.class.php @@ -0,0 +1,220 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/realfield.class.php + * \ingroup core + * \brief File of class to real field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to real field + */ +class RealField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $value = !$this->isEmptyValue($fieldInfos, $value) ? price((double) $value) : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib . $autoFocus); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? price((double) $value) : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'maxwidth75'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isNumeric($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + $value = GETPOST($htmlName, 'restricthtml'); + $value = str_replace(',', '.', $value); + + return $this->verifyFieldValue($fieldInfos, $key, $value); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = (double) price2num(GETPOST($htmlName, 'alphanohtml')); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 1); + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/selectfield.class.php b/htdocs/core/class/fields/selectfield.class.php new file mode 100644 index 00000000000..45182fbcb64 --- /dev/null +++ b/htdocs/core/class/fields/selectfield.class.php @@ -0,0 +1,271 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/selectfield.class.php + * \ingroup core + * \brief File of class to select field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonselectfield.class.php'; + + +/** + * Class to select field + */ +class SelectField extends CommonSelectField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $conf; + + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $htmlName = $keyPrefix . $key . $keySuffix; + $value = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value))); + + $optionsList = array(); + $options = $this->getOptions($fieldInfos, $key); + foreach ($options as $optionKey => $optionInfos) { + $options[$optionKey] = $optionInfos['label']; + } + + return self::$form->multiselectarray($htmlName, $optionsList, $value, 0, 0, $moreCss, 0, 0, $moreAttrib, '', '', (int) (!empty($conf->use_javascript_ajax) && !getDolGlobalString('MAIN_EXTRAFIELDS_DISABLE_SELECT2'))); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $placeHolder = $fieldInfos->inputPlaceholder; + if (!empty($placeHolder)) $placeHolder = ' placeholder="' . dolPrintHTMLForAttribute($placeHolder) . '"'; + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + + $selectedValue = is_null($value) || $this->isEmptyValue($fieldInfos, $value) ? '' : (string) $value; + + $options = $this->getOptions($fieldInfos, $key, true); + + return self::$form->selectarray($htmlName, $options, $selectedValue, 0, 0, 0, $moreAttrib . $placeHolder . $autoFocus, 0, 0, 0, '', $moreCss); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $value = (string) $value; + + if (!$this->isEmptyValue($fieldInfos, $value)) { + $options = $this->getOptions($fieldInfos, $key); + foreach ($options as $optionKey => $optionInfos) { + if (((string) $optionKey) == $value) { + $value = $optionInfos['label']; + break; + } + } + } + + return $value; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'minwidth400'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + global $langs; + $value = (string) $value; + + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + $options = $this->getOptions($fieldInfos, $key); + if (!isset($options[$value])) { + self::$validator->error = $langs->trans('RequireValidValue'); + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + $value = GETPOST($htmlName, 'restricthtml'); + $value = trim($value); + + return $this->verifyFieldValue($fieldInfos, $key, $value); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alphanohtml'); + } else { + $value = $defaultValue; + } + + return $this->isEmptyValue($fieldInfos, $value) ? '' : $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'array'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value) && is_array($value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + $field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key)); + + $tmp = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'"; + return " AND " . $field . " IN (" . $this->db->sanitize($tmp, 1) . ")"; + } + + return ''; + } + + /** + * Get list of options + * + * @param FieldInfos $fieldInfos Array of properties for field to show + * @param string $key Key of field + * @param bool $addEmptyValue Add also empty value if needed + * @param bool $reload Force reload options + * @return array + */ + public function getOptions($fieldInfos, $key, $addEmptyValue = false, $reload = false) + { + return parent::getOptions($fieldInfos, $key, $addEmptyValue, $reload); + } +} diff --git a/htdocs/core/class/fields/sellistfield.class.php b/htdocs/core/class/fields/sellistfield.class.php new file mode 100644 index 00000000000..61e5ab09469 --- /dev/null +++ b/htdocs/core/class/fields/sellistfield.class.php @@ -0,0 +1,298 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/sellistfield.class.php + * \ingroup core + * \brief File of class to sellist field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonsellistfield.class.php'; + + +/** + * Class to sellist field + */ +class SellistField extends CommonSellistField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array('', array()); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $conf; + + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $htmlName = $keyPrefix . $key . $keySuffix; + + $optionsList = array(); + $options = $this->getOptions($fieldInfos, $key); + foreach ($options as $optionKey => $optionInfos) { + $options[$optionKey] = $optionInfos['label']; + } + + return self::$form->multiselectarray($htmlName, $optionsList, $value, 0, 0, $moreCss, 0, 0, $moreAttrib, '', '', (int) (!empty($conf->use_javascript_ajax) && !getDolGlobalString('MAIN_EXTRAFIELDS_DISABLE_SELECT2'))); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $conf; + + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $placeHolder = $fieldInfos->inputPlaceholder; + if (!empty($placeHolder)) $placeHolder = ' placeholder="' . dolPrintHTMLForAttribute($placeHolder) . '"'; + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + $selectedValue = is_null($value) || $this->isEmptyValue($fieldInfos, $value) ? '' : (string) $value; + + if (!empty($conf->use_javascript_ajax) && getDolGlobalString('MAIN_EXTRAFIELDS_ENABLE_NEW_SELECT2')) { + $objectId = isset($fieldInfos->otherParams['objectId']) ? (int) $fieldInfos->otherParams['objectId'] : (isset($fieldInfos->object) && is_object($fieldInfos->object) ? $fieldInfos->object->id : 0); + $objectType = isset($fieldInfos->otherParams['objectType']) ? (int) $fieldInfos->otherParams['objectType'] : (isset($fieldInfos->object) && is_object($fieldInfos->object) ? $fieldInfos->object->element : ''); + $printMode = empty($fieldInfos->mode) ? 'view' : $fieldInfos->mode; + $options = $this->getOptions($fieldInfos, $key, false, false, $selectedValue); + + // TODO add dependency support (set dependencyvalue with dependency field value get by JS) + $ajaxData = array( + 'objecttype' => $objectType, + 'objectid' => $objectId, + 'objectkey' => $key, + 'mode' => $printMode, + 'value' => $selectedValue, + 'dependencyvalue' => '', + ); + + $out = self::$form->inputSelectAjax($htmlName, $options, $selectedValue, self::$ajaxUrl, $ajaxData, $moreCss, $moreAttrib . $placeHolder . $autoFocus); + } else { + $options = $this->getOptions($fieldInfos, $key, true); + + $out = self::$form->selectarray($htmlName, $options, $selectedValue, 0, 0, 0, $moreAttrib . $placeHolder . $autoFocus, 0, 0, 0, '', $moreCss); + } + + return $out; + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $value = (string) $value; + + if (!$this->isEmptyValue($fieldInfos, $value)) { + $options = $this->getOptions($fieldInfos, $key, false, false, $value); + if (isset($options[$value])) { + $out = $options[$value]['label']; + + $optionParams = $this->getOptionsParams($fieldInfos->options); + if ($optionParams['tableName'] == 'categorie' && !empty($optionParams['categoryType'])) { + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $c = new Categorie($this->db); + $c->fetch((int) $value); + $color = ' style="background: #' . ($c->color ? $c->color : 'bbb') . ';"'; + $label = img_object('', 'category') . ' ' . $value; + $out = '
    • ' . $label . '
    '; + } + + $value = $out; + } + } + + return $value; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'minwidth400'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + $optionParams = $this->getOptionsParams($fieldInfos->options); + if (!self::$validator->isInDb($value, $optionParams['tableName'], $optionParams['keyField'])) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + $value = GETPOST($htmlName, 'restricthtml'); + $value = trim($value); + + return $this->verifyFieldValue($fieldInfos, $key, $value); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alphanohtml'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'array'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!empty($value) && is_array($value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + $field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key)); + + $tmp = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'"; + return " AND " . $field . " IN (" . $this->db->sanitize($tmp, 1) . ")"; + } + + return ''; + } + + /** + * Get list of options + * + * @param FieldInfos $fieldInfos Array of properties for field to show + * @param string $key Key of field + * @param bool $addEmptyValue Add also empty value if needed + * @param bool $reload Force reload options + * @param string|array $selectedValues Only selected values + * @return array + */ + public function getOptions($fieldInfos, $key, $addEmptyValue = false, $reload = false, $selectedValues = array()) + { + return parent::getOptions($fieldInfos, $key, $addEmptyValue, $reload, $selectedValues); + } +} diff --git a/htdocs/core/class/fields/starsfield.class.php b/htdocs/core/class/fields/starsfield.class.php new file mode 100644 index 00000000000..37187235bed --- /dev/null +++ b/htdocs/core/class/fields/starsfield.class.php @@ -0,0 +1,242 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/starsfield.class.php + * \ingroup core + * \brief File of class to stars field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to stars field + */ +class StarsField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array('', -1); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $langs; + + $size = (int) $fieldInfos->size; + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $value = (int) $value; + $htmlName = $keyPrefix . $key . $keySuffix; + + $options = array(); + for ($i = 0; $i <= $size; $i++) { + // TODO ajouter la tranduction + $options[$i] = $langs->trans("StarsFieldValue", $i); + } + + return self::$form->selectarray($htmlName, $options, $value, 1, 0, 0, $moreAttrib, 0, 0, 0, '', $moreCss); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $size = (int) $fieldInfos->size; + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $value = (int) $value; + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputStars($htmlName, $size, $value, $moreCss, $moreAttrib . $autoFocus); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $size = (int) $fieldInfos->size; + $value = (int) $value; + + return self::$form->outputStars($size, $value); + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $fieldInfos->minValue = 0; + $fieldInfos->maxValue = (int) $fieldInfos->size; + + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isNumeric($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + return $this->verifyFieldValue($fieldInfos, $key, GETPOST($htmlName, 'restricthtml')); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOSTINT($htmlName); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOSTINT($htmlName); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + $value = (int) $value; + + if ($value >= 0) { + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), (string) $value, 1); + } + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/textfield.class.php b/htdocs/core/class/fields/textfield.class.php new file mode 100644 index 00000000000..e588de8fcf5 --- /dev/null +++ b/htdocs/core/class/fields/textfield.class.php @@ -0,0 +1,229 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/textfield.class.php + * \ingroup core + * \brief File of class to text field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; + + +/** + * Class to text field + */ +class TextField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputText($htmlName, (string) $value, $moreCss, $moreAttrib, $fieldInfos->options); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + if (!empty($fieldInfos->options)) { + $value = str_replace(',', "\n", (string) $value); + } + + return dol_htmlentitiesbr((string) $value); + } + + return ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + return parent::verifyFieldValue($fieldInfos, $key, $value); + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + $value = GETPOST($htmlName, 'restricthtml'); + + return $this->verifyFieldValue($fieldInfos, $key, $value); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + if (!empty($fieldInfos->getPostCheck)) { + $value = GETPOST($htmlName, $fieldInfos->getPostCheck); + } else { + $value = GETPOST($htmlName, 'nohtml'); + if (!empty($fieldInfos->options) && !empty($fieldInfos->multiInput)) { + $tmpArrayMultiSelect = GETPOST($htmlName . '_multiselect', 'array'); + foreach ($tmpArrayMultiSelect as $tmpValue) { + $value .= (!empty($value) ? "," : "") . $tmpValue; + } + } + } + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 0); + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/timestampfield.class.php b/htdocs/core/class/fields/timestampfield.class.php new file mode 100644 index 00000000000..288c9254fcc --- /dev/null +++ b/htdocs/core/class/fields/timestampfield.class.php @@ -0,0 +1,258 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/timestampfield.class.php + * \ingroup core + * \brief File of class to timestamp field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to timestamp field + */ +class TimestampField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $langs; + + // TODO Must also support $moreCss ? + + $htmlName = $keyPrefix . $key . $keySuffix; + $prefill = array( + 'start' => $value['start'] ?? '', + 'end' => $value['end'] ?? '', + ); + + // Search filter on a date field shows two inputs to select a date range + $out = '
    '; + $out .= self::$form->selectDate($prefill['start'], $htmlName . '_start', 1, 1, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"), 'tzuserrel'); + $out .= '
    '; + $out .= self::$form->selectDate($prefill['end'], $htmlName . '_end', 1, 1, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"), 'tzuserrel'); + $out .= '
    '; + + return $out; + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $required = $fieldInfos->required ? 1 : 0; + $htmlName = $keyPrefix . $key . $keySuffix; + + // Do not show current date when field not required (see selectDate() method) + if (!$required && $this->isEmptyValue($fieldInfos, $value)) { + $value = '-1'; + } + + // TODO Must also support $moreAttrib and $moreCss ? + return self::$form->selectDate($value, $htmlName, 1, 1, $required, '', 1, 1, 0, 1, '', '', '', 1, '', '', 'tzuserrel'); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? dol_print_date($value, 'dayhour', 'tzuserrel') : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss ? $defaultCss : 'minwidth200imp'); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isTimestamp($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName . 'hour') || GETPOSTISSET($htmlName . 'min') || GETPOSTISSET($htmlName . 'sec') || GETPOSTISSET($htmlName . 'month') || GETPOSTISSET($htmlName . 'day') || GETPOSTISSET($htmlName . 'year')) { + $value = dol_mktime(GETPOSTINT($htmlName . 'hour'), GETPOSTINT($htmlName . 'min'), GETPOSTINT($htmlName . 'sec'), GETPOSTINT($htmlName . 'month'), GETPOSTINT($htmlName . 'day'), GETPOSTINT($htmlName . 'year'), 'tzuserrel'); // for date without hour, we use gmt + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName . '_startmonth') || GETPOSTISSET($htmlName . '_startday') || GETPOSTISSET($htmlName . '_startyear')) { + $start = dol_mktime(0, 0, 0, GETPOSTINT($htmlName . '_startmonth'), GETPOSTINT($htmlName . '_startday'), GETPOSTINT($htmlName . '_startyear'), 'tzuserrel'); + } else { + $start = is_array($defaultValue) && isset($defaultValue['start']) ? $defaultValue['start'] : ''; + } + + if (GETPOSTISSET($htmlName . '_endmonth') || GETPOSTISSET($htmlName . '_endday') || GETPOSTISSET($htmlName . '_endyear')) { + $end = dol_mktime(23, 59, 59, GETPOSTINT($htmlName . '_endmonth'), GETPOSTINT($htmlName . '_endday'), GETPOSTINT($htmlName . '_endyear'), 'tzuserrel'); + } else { + $end = is_array($defaultValue) && isset($defaultValue['end']) ? $defaultValue['end'] : ''; + } + + return array( + 'start' => $start, + 'end' => $end, + ); + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + $field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key)); + $sql = ''; + + if (is_array($value)) { + $hasStart = !is_null($value['start']) && $value['start'] !== ''; + $hasEnd = !is_null($value['start']) && $value['start'] !== ''; + if ($hasStart && $hasEnd) { + $sql = " AND (" . $field . " BETWEEN '" . $this->db->idate($value['start']) . "' AND '" . $this->db->idate($value['end']) . "')"; + } elseif ($hasStart) { + $sql = " AND " . $field . " >= '" . $this->db->idate($value['start']) . "'"; + } elseif ($hasEnd) { + $sql = " AND " . $field . " <= '" . $this->db->idate($value['end']) . "'"; + } + } elseif (is_numeric($value)) { + $sql = " AND " . $field . " = '" . $this->db->idate($value) . "'"; + } + + return $sql; + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/urlfield.class.php b/htdocs/core/class/fields/urlfield.class.php new file mode 100644 index 00000000000..20040274607 --- /dev/null +++ b/htdocs/core/class/fields/urlfield.class.php @@ -0,0 +1,217 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/urlfield.class.php + * \ingroup core + * \brief File of class to url field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to url field + */ +class UrlField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib . $autoFocus); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? dol_print_url((string) $value, '_blank', 32, 1) : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + $result = parent::verifyFieldValue($fieldInfos, $key, $value); + if ($result && !$this->isEmptyValue($fieldInfos, $value)) { + if (!self::$validator->isUrl($value)) { + return false; + } + + $result = true; + } + + return $result; + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alphanohtml'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 0); + } + + return ''; + } +} diff --git a/htdocs/core/class/fields/varcharfield.class.php b/htdocs/core/class/fields/varcharfield.class.php new file mode 100644 index 00000000000..15c4dc042a8 --- /dev/null +++ b/htdocs/core/class/fields/varcharfield.class.php @@ -0,0 +1,213 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fields/varcharfield.class.php + * \ingroup core + * \brief File of class to varchar field + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to varchar field + */ +class VarcharField extends CommonField +{ + /** + * @var array List of value deemed as empty (null always deemed as empty) + */ + public $emptyValues = array(''); + + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $moreAttrib); + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + $size = (int) $fieldInfos->size; + $maxLength = ''; // $size > 0 ? ' maxlength="' . $size . '"' : ''; // TODO rework, wrong method + $moreCss = $this->getInputCss($fieldInfos, $moreCss); + $moreAttrib = trim((string) $moreAttrib); + if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib; + $placeHolder = $fieldInfos->inputPlaceholder; + if (!empty($placeHolder)) $placeHolder = ' placeholder="' . dolPrintHTMLForAttribute($placeHolder) . '"'; + $autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : ''; + $htmlName = $keyPrefix . $key . $keySuffix; + + return self::$form->inputType('text', $htmlName, (string) $value, $htmlName, $moreCss, $maxLength . $moreAttrib . $placeHolder . $autoFocus); + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + return !$this->isEmptyValue($fieldInfos, $value) ? dol_htmlentitiesbr((string) $value) : ''; + } + + /** + * Get input CSS + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $moreCss Value for css to define style/length of field. + * @param string $defaultCss Default value for css to define style/length of field. + * @return string + * @see self::printInputSearchField(), self::printInputField() + */ + public function getInputCss($fieldInfos, $moreCss = '', $defaultCss = '') + { + return parent::getInputCss($fieldInfos, $moreCss, $defaultCss); + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + * @see self::printInputField() + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + return parent::verifyFieldValue($fieldInfos, $key, $value); + } + + /** + * Verify if the field value from GET/POST is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + * @see self::printInputField() + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + return parent::verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputField() + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $check = $key == 'lang' ? 'aZ09' : 'alphanohtml'; + $value = GETPOST($htmlName, $check); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + * @see self::printInputSearchField() + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + $htmlName = $keyPrefix . $key . $keySuffix; + + if (GETPOSTISSET($htmlName)) { + $value = GETPOST($htmlName, 'alpha'); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get sql filter for search field + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return string + * @see self::printInputSearchField(), self::getPostSearchFieldValue() + */ + public function sqlFilterSearchField($fieldInfos, $key, $value) + { + if (!$this->isEmptyValue($fieldInfos, $value)) { + $alias = $fieldInfos->sqlAlias ?? 't.'; + + return natural_search($alias . ($fieldInfos->nameInTable ?? $key), $value, 0); + } + + return ''; + } +} diff --git a/htdocs/core/class/fieldsmanager.class.php b/htdocs/core/class/fieldsmanager.class.php new file mode 100644 index 00000000000..77ca467acaa --- /dev/null +++ b/htdocs/core/class/fieldsmanager.class.php @@ -0,0 +1,1309 @@ + + * Copyright (C) 2002-2003 Jean-Louis Bergamo + * Copyright (C) 2004 Sebastien Di Cintio + * Copyright (C) 2004 Benoit Mortier + * Copyright (C) 2009-2012 Laurent Destailleur + * Copyright (C) 2009-2012 Regis Houssin + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2015 Charles-Fr BENKE + * Copyright (C) 2016 Raphaël Doursenaud + * Copyright (C) 2017 Nicolas ZABOURI + * Copyright (C) 2018-2022 Frédéric France + * Copyright (C) 2022 Antonin MARCHAL + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/fieldsmanager.class.php + * \ingroup core + * \brief File of class to manage fields + */ + +require_once DOL_DOCUMENT_ROOT . '/core/class/fieldinfos.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/fields/commonfield.class.php'; + + +/** + * Class to manage fields + */ +class FieldsManager +{ + /** + * @var DoliDB Database handler. + */ + public $db; + + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * @var string[] Array of Error code (or message) + */ + public $errors = array(); + + /** + * @var array To store error results of ->validateField() + */ + public $validateFieldsErrors = array(); + + /** + * @var string Path to fields classes + */ + public $fieldsPath = '/core/class/fields/'; + + /** + * @var array Field classes cached + */ + public static $fieldClasses = array(); + + /** + * @var array,extraField:array}>> Field infos cached (array,extraField:array}>>) + */ + public static $fieldInfos = array(); + + /** + * @var array>|null Array with boolean of status of groups + */ + public $expand_display = array(); + + ///** + // * @var array Array of type to label + // */ + //public static $type2label = array( + // 'varchar' => 'String1Line', + // 'text' => 'TextLongNLines', + // 'html' => 'HtmlText', + // 'int' => 'Int', + // 'double' => 'Float', + // 'date' => 'Date', + // 'datetime' => 'DateAndTime', + // 'duration' => 'Duration', + // //'datetimegmt'=>'DateAndTimeUTC', + // 'boolean' => 'Boolean', + // 'price' => 'ExtrafieldPrice', + // 'pricecy' => 'ExtrafieldPriceWithCurrency', + // 'phone' => 'ExtrafieldPhone', + // 'email' => 'ExtrafieldMail', + // 'url' => 'ExtrafieldUrl', + // 'ip' => 'ExtrafieldIP', + // 'icon' => 'Icon', + // 'password' => 'ExtrafieldPassword', + // 'radio' => 'ExtrafieldRadio', + // 'select' => 'ExtrafieldSelect', + // 'sellist' => 'ExtrafieldSelectList', + // 'checkbox' => 'ExtrafieldCheckBox', + // 'chkbxlst' => 'ExtrafieldCheckBoxFromList', + // 'link' => 'ExtrafieldLink', + // 'point' => 'ExtrafieldPointGeo', + // 'multipts' => 'ExtrafieldMultiPointGeo', + // 'linestrg' => 'ExtrafieldLinestringGeo', + // 'polygon' => 'ExtrafieldPolygonGeo', + // 'separate' => 'ExtrafieldSeparator', + // 'stars' => 'ExtrafieldStars', + // //'real' => 'ExtrafieldReal', + //); + + + /** + * Constructor + * + * @param DoliDB $db Database handler + * @param Form|null $form Specific form handler + */ + public function __construct($db, $form = null) + { + $this->db = $db; + $this->error = ''; + $this->errors = array(); + + if (isset($form)) { + CommonField::setForm($form); + } + } + + /** + * Get field handler for the provided type + * + * @param string $type Field type + * @return CommonField|null + */ + public function getFieldClass($type) + { + global $hookmanager, $langs; + + $type = trim($type); + + if (!isset(self::$fieldClasses[$type])) { + $field = null; + $parameters = array( + 'type' => $type, + // @phan-suppress-next-line PhanPluginConstantVariableNull + 'field' => &$field, + ); + + $hookmanager->executeHooks('getFieldClass', $parameters, $this); // Note that $object may have been modified by hook + // @phpstan-ignore-next-line @phan-suppress-next-line PhanPluginConstantVariableNull + if (isset($field) && is_object($field)) { + self::$fieldClasses[$type] = $field; + } else { + $filename = strtolower($type) . 'field.class.php'; + $classname = ucfirst($type) . 'Field'; + + // Load class file + dol_include_once(rtrim($this->fieldsPath, '/') . '/' . $filename); + if (!class_exists($classname)) { + @include_once DOL_DOCUMENT_ROOT . '/core/class/fields/' . $filename; + } + + if (class_exists($classname)) { + self::$fieldClasses[$type] = new $classname($this->db); + } else { + $langs->load("errors"); + $this->errors[] = $langs->trans('ErrorFieldClassNotFoundForClassName', $classname, $type); + return null; + } + } + } + + $field = self::$fieldClasses[$type]; + $field->clearErrors(); + + return $field; + } + + /** + * Get all fields handler available + * + * @return array + */ + public function getAllFields() + { + // Todo to make + return self::$fieldClasses; + } + + /** + * clear errors + * + * @return void + */ + public function clearErrors() + { + $this->error = ''; + $this->errors = array(); + } + + /** + * Method to output saved errors + * + * @param string $separator Separator between each error + * @return string String with errors + */ + public function errorsToString($separator = ', ') + { + return $this->error . (is_array($this->errors) ? (!empty($this->error) ? $separator : '') . implode($separator, $this->errors) : ''); + } + + /** + * clear validation message result for a field + * + * @param string $fieldKey Key of attribute to clear + * @return void + */ + public function clearFieldError($fieldKey) + { + $this->error = ''; + unset($this->validateFieldsErrors[$fieldKey]); + } + + /** + * set validation error message a field + * + * @param string $fieldKey Key of attribute + * @param string $msg the field error message + * @return void + */ + public function setFieldError($fieldKey, $msg = '') + { + global $langs; + if (empty($msg)) { + $msg = $langs->trans("UnknownError"); + } + + $this->error = $this->validateFieldsErrors[$fieldKey] = $msg; + } + + /** + * get field error message + * + * @param string $fieldKey Key of attribute + * @return string Error message of validation ('' if no error) + */ + public function getFieldError($fieldKey) + { + if (!empty($this->validateFieldsErrors[$fieldKey])) { + return $this->validateFieldsErrors[$fieldKey]; + } + return ''; + } + + /** + * get field error icon + * + * @param string $fieldValidationErrorMsg message to add in tooltip + * @return string html output + */ + public function getFieldErrorIcon($fieldValidationErrorMsg) + { + $out = ''; + + if (!empty($fieldValidationErrorMsg) && function_exists('getFieldErrorIcon')) { + $out .= ' ' . getFieldErrorIcon($fieldValidationErrorMsg); + } + + return $out; + } + + /** + * Get list of fields infos for the provided mode into X columns + * + * @param CommonObject $object Object handler + * @param ExtraFields $extrafields ExtraFields handler + * @param string $mode Get the fields infos for the provided mode ('create', 'edit', 'view', 'list') + * @param int $nbColumn Split fields infos into X columns + * @param array $breakKeys Key used for break on each column (ex: array(1 => 'total_ht', ...)) + * @param array $params Other params + * @return array{columns:array>,hiddenFields:array} List of fields info by column and hidden + */ + public function getAllFieldsInfos(&$object, &$extrafields = null, $mode = 'view', $nbColumn = 2, $breakKeys = array(), $params = array()) + { + global $hookmanager, $langs; + + // Get object fields + $fields = $this->getAllObjectFieldsInfos($object, $mode, $params); + + // Old sort + if (!getDolGlobalInt('MAIN_FIELDS_SORT_WITH_EXTRA_FIELDS')) { + $fields = dol_sort_array($fields, 'position'); + } + + // Get extra fields + $fields2 = $this->getAllExtraFieldsInfos($object, $extrafields, $mode, $params); + $fields = array_merge($fields, $fields2); + + // New sort + if (getDolGlobalInt('MAIN_FIELDS_SORT_WITH_EXTRA_FIELDS')) { + $fields = dol_sort_array($fields, 'position'); + } + + // Split in columns + $idxColumn = 1; + $columns = array(); + $hiddenFields = array(); + $columns[$idxColumn] = array(); + $nbVisibleFields = 0; + foreach ($fields as $field) { + if ($field->visible) { + $nbVisibleFields++; + } + } + $nbFieldsByColumn = ceil($nbVisibleFields / $nbColumn); + $breakKey = $breakKeys[$idxColumn] ?? ''; + $idxField = 0; + foreach ($fields as $key => $field) { + if ($idxColumn < $nbColumn && ((!empty($breakKey) && $key == $breakKey) || (empty($breakKey) && $idxField == $nbFieldsByColumn))) { + $idxColumn++; + $idxField = 0; + $columns[$idxColumn] = array(); + } + + if ($field->visible) { + if ($field->type != 'separate') { + $idxField++; + } + + // Add field into column + $columns[$idxColumn][$key] = $field; + } else { + $hiddenFields[$key] = $field; + } + } + + // Add column not created + for ($idxColumn = 1; $idxColumn <= $nbColumn; $idxColumn++) { + if (!isset($columns[$idxColumn])) { + $columns[$idxColumn] = array(); + } + } + + $parameters = array( + 'object' => &$object, + 'extrafields' => &$extrafields, + 'mode' => $mode, + 'nbColumn' => $nbColumn, + 'breakKeys' => $breakKeys, + 'params' => $params, + 'columns' => &$columns, + 'hiddenFields' => &$hiddenFields, + ); + + $hookmanager->executeHooks('getFieldInfosFromObjectField', $parameters, $this); // Note that $object may have been modified by hook + + return array( + 'columns' => $columns, + 'hiddenFields' => $hiddenFields, + ); + } + + /** + * Get list of object fields infos + * + * @param CommonObject $object Object handler + * @param string $mode Get the fields infos for the provided mode ('create', 'edit', 'view', 'list') + * @param array $params Other params + * @return array List of fields infos + */ + public function getAllObjectFieldsInfos(&$object, $mode = 'view', $params = array()) + { + global $hookmanager; + + // Get object fields + $fields = array(); + // @phpstan-ignore-next-line + if (isset($object->fields) && is_array($object->fields)) { + $keyPrefix = getDolGlobalInt('MAIN_FIELDS_NEW_OBJECT_KEY_PREFIX') ? 'object_' : ''; + foreach ($object->fields as $key => $field) { + $fieldInfos = $this->getFieldInfosFromObjectField($object, $key, $mode, $params); + $fields[$keyPrefix . $key] = $fieldInfos; + } + } + + $parameters = array( + 'object' => &$object, + 'mode' => $mode, + 'params' => $params, + 'fields' => &$fields, + ); + + $hookmanager->executeHooks('getAllObjectFieldsInfos', $parameters, $this); // Note that $object may have been modified by hook + + return $fields; + } + + /** + * Get list of extra fields infos + * + * @param CommonObject $object Object handler + * @param ExtraFields $extrafields ExtraFields handler + * @param string $mode Get the fields infos for the provided mode ('create', 'edit', 'view', 'list') + * @param array $params Other params + * @return array List of fields infos + */ + public function getAllExtraFieldsInfos(&$object, &$extrafields = null, $mode = 'view', $params = array()) + { + global $hookmanager; + + // Get extra fields + $fields = array(); + if (isset($extrafields->attributes[$object->table_element]) && is_array($extrafields->attributes[$object->table_element])) { + $keyPrefix = 'options_'; + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { + $fieldInfos = $this->getFieldInfosFromExtraField($object, $extrafields, $key, $mode, $params); + $fields[$keyPrefix . $key] = $fieldInfos; + } + } + + $parameters = array( + 'object' => &$object, + 'extrafields' => &$extrafields, + 'mode' => $mode, + 'params' => $params, + 'fields' => &$fields, + ); + + $hookmanager->executeHooks('getAllExtraFieldsInfos', $parameters, $this); // Note that $object may have been modified by hook + + return $fields; + } + + /** + * Get list of fields infos for the provided mode into X columns + * + * @param string $key Field key (begin by object_ for object or options_ for extrafields) + * @param CommonObject $object Object handler + * @param ExtraFields $extrafields ExtraFields handler + * @param string $mode Get the fields infos for the provided mode ('create', 'edit', 'view', 'list') + * @param array $params Other params + * @return FieldInfos|null Get field info or null if not found + */ + public function getFieldsInfos($key, &$object, &$extrafields = null, $mode = 'view', $params = array()) + { + global $langs; + + $fieldInfos = null; + + $patternObjectPrefix = getDolGlobalInt('MAIN_FIELDS_NEW_OBJECT_KEY_PREFIX') ? 'object_' : ''; + if (preg_match('/^options_(.*)/i', $key, $matches)) { + $fieldKey = $matches[1]; + $fieldInfos = $this->getFieldInfosFromExtraField($object, $extrafields, $fieldKey, $mode, $params); + } elseif (preg_match('/^' . $patternObjectPrefix . '(.*)/i', $key, $matches)) { + $fieldKey = $matches[2]; + $fieldInfos = $this->getFieldInfosFromObjectField($object, $fieldKey, $mode, $params); + } + + return $fieldInfos; + } + + /** + * Get field infos from object field infos + * + * @param CommonObject $object Object handler + * @param string $key Field key + * @param string $mode Get the fields infos for the provided mode ('create', 'edit', 'view', 'list') + * @param array $params Other params + * @return FieldInfos|null Properties of the field or null if field not found + */ + public function getFieldInfosFromObjectField(&$object, $key, $mode = 'view', $params = array()) + { + global $hookmanager; + + if (!isset($object->fields[$key])) { + return null; + } + + if (isset(self::$fieldInfos[$object->element][$mode]['object'][$key])) { + return self::$fieldInfos[$object->element][$mode]['object'][$key]; + } + + $attributes = $object->fields[$key]; + + $fieldInfos = new FieldInfos(); + $fieldInfos->fieldType = FieldInfos::FIELD_TYPE_OBJECT; + $fieldInfos->originType = $attributes['type'] ?? ''; + $fieldInfos->size = $attributes['length'] ?? ''; + $fieldInfos->label = $attributes['label'] ?? ''; + $fieldInfos->langFile = $attributes['langfile'] ?? ''; + $fieldInfos->sqlAlias = $attributes['alias'] ?? null; + $fieldInfos->picto = $attributes['picto'] ?? ''; + $fieldInfos->position = $attributes['position'] ?? 0; + $fieldInfos->required = ($attributes['notnull'] ?? 0) > 0; + $fieldInfos->alwaysEditable = !empty($attributes['alwayseditable']); + $fieldInfos->defaultValue = $attributes['default'] ?? ''; + $fieldInfos->css = $attributes['css'] ?? ''; + $fieldInfos->viewCss = $attributes['cssview'] ?? ''; + $fieldInfos->listCss = $attributes['csslist'] ?? ''; + $fieldInfos->inputPlaceholder = $attributes['placeholder'] ?? ''; + $fieldInfos->help = $attributes['help'] ?? ''; + $fieldInfos->listHelp = $attributes['helplist'] ?? ''; + $fieldInfos->showOnComboBox = !empty($attributes['showoncombobox']); + $fieldInfos->inputDisabled = !empty($attributes['disabled']); + $fieldInfos->inputAutofocus = !empty($attributes['autofocusoncreate']) && $mode == 'create'; + $fieldInfos->comment = $attributes['comment'] ?? ''; + $fieldInfos->listTotalizable = !empty($attributes['isameasure']) && $attributes['isameasure'] == 1; + $fieldInfos->validateField = !empty($attributes['validate']); + $fieldInfos->copyToClipboard = $attributes['copytoclipboard'] ?? 0; + $fieldInfos->tdCss = $attributes['tdcss'] ?? ''; + $fieldInfos->multiInput = !empty($attributes['multiinput']); + $fieldInfos->nameInClass = $attributes['nameinclass'] ?? $key; + $fieldInfos->nameInTable = $attributes['nameintable'] ?? $key; + $fieldInfos->getNameUrlParams = $attributes['get_name_url_params'] ?? null; + $fieldInfos->showOnHeader = !empty($attributes['showonheader']); + + // TODO set nameinclass = "id" in fields "rowid" + if ($fieldInfos->nameInClass == 'rowid') { + $fieldInfos->nameInClass = 'id'; + } + + $enabled = $attributes['enabled'] ?? '1'; + $visibility = $attributes['visible'] ?? '1'; + $perms = empty($attributes['noteditable']) ? '1' : '0'; + + $this->setCommonFieldInfos($fieldInfos, $object, $extrafields, $key, $mode, $enabled, $visibility, $perms, $params); + + // Special case that force options and type ($type can be integer, varchar, ...) + if (!empty($attributes['arrayofkeyval']) && is_array($attributes['arrayofkeyval'])) { + $fieldInfos->options = $attributes['arrayofkeyval']; + // Special case that prevent to force $type to have multiple input @phan-suppress-next-line PhanTypeMismatchProperty + if (!$fieldInfos->multiInput) { + $fieldInfos->type = (($fieldInfos->type == 'checkbox') ? $fieldInfos->type : 'select'); + } + } + + $parameters = array( + 'object' => &$object, + 'key' => $key, + 'mode' => $mode, + 'fieldInfos' => &$fieldInfos, + ); + + $hookmanager->executeHooks('getFieldInfosFromObjectField', $parameters, $this); // Note that $object may have been modified by hook + + self::$fieldInfos[$object->element][$mode]['object'][$key] = $fieldInfos; + return $fieldInfos; + } + + /** + * Get field infos from extra field infos + * + * @param CommonObject $object Object handler + * @param ExtraFields $extrafields Extrafields handler + * @param string $key Field key + * @param string $mode Get the fields infos for the provided mode ('create', 'edit', 'view', 'list') + * @param array $params Other params + * @return FieldInfos|null Properties of the field or null if not found + */ + public function getFieldInfosFromExtraField(&$object, &$extrafields, $key, $mode = 'view', $params = array()) + { + global $hookmanager; + + if (!isset($extrafields->attributes[$object->table_element]['label'][$key])) { + return null; + } + + if (isset(self::$fieldInfos[$object->element][$mode]['extraField'][$key])) { + return self::$fieldInfos[$object->element][$mode]['extraField'][$key]; + } + + $attributes = $extrafields->attributes[$object->table_element]; + + $fieldInfos = new FieldInfos(); + $fieldInfos->fieldType = FieldInfos::FIELD_TYPE_EXTRA_FIELD; + $fieldInfos->originType = $attributes['type'][$key] ?? ''; + $fieldInfos->label = $attributes['label'][$key] ?? ''; + $fieldInfos->position = $attributes['pos'][$key] ?? 0; + $fieldInfos->required = !empty($attributes['required'][$key]); + $fieldInfos->defaultValue = $attributes['default'][$key] ?? ''; + $fieldInfos->css = $attributes['css'][$key] ?? ''; + $fieldInfos->help = $attributes['help'][$key] ?? ''; + $fieldInfos->size = $attributes['size'][$key] ?? ''; + $fieldInfos->computed = $attributes['computed'][$key] ?? ''; + $fieldInfos->unique = !empty($attributes['unique'][$key]); + $fieldInfos->alwaysEditable = !empty($attributes['alwayseditable'][$key]); + $fieldInfos->emptyOnClone = !empty($attributes['emptyonclone'][$key]); + $fieldInfos->langFile = $attributes['langfile'][$key] ?? ''; + $fieldInfos->printable = !empty($attributes['printable'][$key]); + $fieldInfos->aiPrompt = $attributes['aiprompt'][$key] ?? ''; + $fieldInfos->viewCss = $attributes['cssview'][$key] ?? ''; + $fieldInfos->listCss = $attributes['csslist'][$key] ?? ''; + $fieldInfos->listTotalizable = !empty($attributes['totalizable'][$key]); + $fieldInfos->options = array_diff_assoc($attributes['param'][$key]['options'] ?? array(), array('' => null)); // For remove case when not defined + $fieldInfos->nameInClass = $key; + $fieldInfos->nameInTable = $key; + + $enabled = $attributes['enabled'][$key] ?? '1'; + $visibility = $attributes['list'][$key] ?? '1'; + $perms = $attributes['perms'][$key] ?? null; + + $this->setCommonFieldInfos($fieldInfos, $object, $extrafields, $key, $mode, $enabled, $visibility, $perms, $params); + + $parameters = array( + 'object' => &$object, + 'extraFields' => &$extrafields, + 'key' => $key, + 'mode' => $mode, + 'fieldInfos' => &$fieldInfos, + ); + + $hookmanager->executeHooks('getFieldInfosFromExtraField', $parameters, $this); // Note that $object may have been modified by hook + + self::$fieldInfos[$object->element][$mode]['extraField'][$key] = $fieldInfos; + return $fieldInfos; + } + + /** + * Set common field infos + * + * @param FieldInfos $fieldInfos Field infos to set with common infos + * @param CommonObject $object Object handler + * @param ExtraFields $extrafields Extrafields handler + * @param string $key Field key + * @param string $mode Get the fields infos for the provided mode ('create', 'edit', 'view', 'list') + * @param string $enabled Condition when the field must be managed (Example: 1 or 'getDolGlobalInt("MY_SETUP_PARAM")' or 'isModEnabled("multicurrency")' ...) + * @param string $visibility Condition when the field must be visible (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form (not create). 5=Visible on list and view form (not create/not update). 6=visible on list and update/view form (not create). Using a negative value means field is not shown by default on list but can be selected for viewing) + * @param string $perms Condition when the field must be editable + * @param array $params Other params + * @return void + */ + public function setCommonFieldInfos(&$fieldInfos, &$object, &$extrafields, $key, $mode = 'view', $enabled = '1', $visibility = '', $perms = null, $params = array()) + { + global $user; + + $fieldInfos->object = &$object; + $fieldInfos->mode = preg_replace('/[^a-z0-9_]/i', '', $mode); + $fieldInfos->type = $fieldInfos->originType; + $fieldInfos->key = $key; + $fieldInfos->otherParams = $params; + + if (preg_match('/^(integer|link):(.*):(.*):(.*):(.*)/i', $fieldInfos->originType, $reg)) { + $fieldInfos->options = array($reg[2] . ':' . $reg[3] . ':' . $reg[4] . ':' . $reg[5] => 'N'); + $fieldInfos->type = 'link'; + } elseif (preg_match('/^(integer|link):(.*):(.*):(.*)/i', $fieldInfos->originType, $reg)) { + $fieldInfos->options = array($reg[2] . ':' . $reg[3] . ':' . $reg[4] => 'N'); + $fieldInfos->type = 'link'; + } elseif (preg_match('/^(integer|link):(.*):(.*)/i', $fieldInfos->originType, $reg)) { + $fieldInfos->options = array($reg[2] . ':' . $reg[3] . ($reg[1] == 'User' ? ':#getnomurlparam1=-1' : '') => 'N'); + $fieldInfos->type = 'link'; + } elseif (preg_match('/^(sellist):(.*):(.*):(.*):(.*)/i', $fieldInfos->originType, $reg)) { + $fieldInfos->options = array($reg[2] . ':' . $reg[3] . ':' . $reg[4] . ':' . $reg[5] => 'N'); + $fieldInfos->type = 'sellist'; + } elseif (preg_match('/^(sellist):(.*):(.*):(.*)/i', $fieldInfos->originType, $reg)) { + $fieldInfos->options = array($reg[2] . ':' . $reg[3] . ':' . $reg[4] => 'N'); + $fieldInfos->type = 'sellist'; + } elseif (preg_match('/^(sellist):(.*):(.*)/i', $fieldInfos->originType, $reg)) { + $fieldInfos->options = array($reg[2] . ':' . $reg[3] => 'N'); + $fieldInfos->type = 'sellist'; + } elseif (preg_match('/^chkbxlst:(.*)/i', $fieldInfos->originType, $reg)) { + $fieldInfos->options = array($reg[1] => 'N'); + $fieldInfos->type = 'chkbxlst'; + } elseif (preg_match('/varchar\((\d+)\)/', $fieldInfos->originType, $reg)) { + $fieldInfos->options = array(); + $fieldInfos->type = 'varchar'; + $fieldInfos->size = $reg[1]; + $fieldInfos->maxLength = (int) $reg[1]; + } elseif (preg_match('/varchar/', $fieldInfos->originType)) { + $fieldInfos->options = array(); + $fieldInfos->type = 'varchar'; + } elseif (preg_match('/stars\((\d+)\)/', $fieldInfos->originType, $reg)) { + $fieldInfos->options = array(); + $fieldInfos->type = 'stars'; + $fieldInfos->size = $reg[1]; + } elseif (preg_match('/integer/', $fieldInfos->originType)) { + $fieldInfos->type = 'int'; + } elseif ($fieldInfos->originType == 'mail') { + $fieldInfos->type = 'email'; + } elseif (preg_match('/^(text):(.*)/i', $fieldInfos->originType, $reg)) { + $fieldInfos->type = 'text'; + $fieldInfos->getPostCheck = $reg[2]; + } elseif (preg_match('/^(html):(.*)/i', $fieldInfos->originType, $reg)) { + $fieldInfos->type = 'html'; + $fieldInfos->getPostCheck = $reg[2]; + } elseif (preg_match('/^double\(([0-9]+,[0-9]+)\)/', $fieldInfos->originType, $reg)) { + $fieldInfos->type = 'double'; + $fieldInfos->size = $reg[1]; + } + + // Set visibility + $visibility = (int) dol_eval((string) $visibility, 1, 1, '2'); + $absVisibility = abs($visibility); + $enabled = (int) dol_eval((string) $enabled, 1, 1, '2'); + $fieldInfos->visible = true; + if (empty($visibility) || + empty($enabled) || + ($mode == 'create' && !in_array($absVisibility, array(1, 3, 6))) || + ($mode == 'edit' && !in_array($absVisibility, array(1, 3, 4))) || + ($mode == 'view' && (!in_array($absVisibility, array(1, 3, 4, 5)) || $fieldInfos->showOnHeader)) || + ($mode == 'list' && $absVisibility == 3) + ) { + $fieldInfos->visible = false; + } + + // Set edit perms + if (isset($perms)) { + $perms = (int) dol_eval((string) $perms, 1, 1, '2'); + } else { + //TODO Improve element and rights detection + $mappingKeyForPerm = array( + 'fichinter' => 'ficheinter', + 'product' => 'produit', + 'project' => 'projet', + 'order_supplier' => 'supplier_order', + 'invoice_supplier' => 'supplier_invoice', + 'shipping' => 'expedition', + 'productlot' => 'stock', + 'facturerec' => 'facture', + 'mo' => 'mrp', + 'salary' => 'salaries', + 'member' => 'adherent', + ); + $keyForPerm = $mappingKeyForPerm[$object->element] ?? $object->element; + + $perms = false; + if (isset($user->rights->$keyForPerm)) { + $perms = $user->hasRight($keyForPerm, 'creer') || $user->hasRight($keyForPerm, 'create') || $user->hasRight($keyForPerm, 'write'); + } + if ($object->element == 'order_supplier' && !getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD')) { + $perms = $user->hasRight('fournisseur', 'commande', 'creer'); + } elseif ($object->element == 'invoice_supplier' && !getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD')) { + $perms = $user->hasRight('fournisseur', 'facture', 'creer'); + } elseif ($object->element == 'delivery') { + $perms = $user->hasRight('expedition', 'delivery', 'creer'); + } elseif ($object->element == 'contact') { + $perms = $user->hasRight('societe', 'contact', 'creer'); + } + } + // Manage always editable of extra field + $isDraft = ((isset($object->statut) && $object->statut == 0) || (isset($object->status) && $object->status == 0)); + if ($mode == 'view' && !$isDraft && !$fieldInfos->alwaysEditable) { + $perms = false; + } + // Case visible only in view so not editable + if ($mode == 'view' && $absVisibility == 5) { + $perms = false; + } + // Case field computed + if (!empty($fieldInfos->computed)) { + $perms = false; + } + $fieldInfos->editable = !empty($perms); + + // Set list info 'checked' + $fieldInfos->listChecked = $mode == 'list' && $visibility > 0; + } + + /** + * Set all values of the object (with extra field) from POST + * + * @param CommonObject $object Object handler + * @param ExtraFields $extrafields Extrafields handler + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $mode Get the fields infos for the provided mode ('create', 'edit', 'view', 'list') + * @param array $params Other params + * @return int Result <0 if KO, >0 if OK + */ + public function setFieldValuesFromPost(&$object, &$extrafields, $keyPrefix = '', $keySuffix = '', $mode = 'view', $params = array()) + { + $result = $this->setObjectFieldValuesFromPost($object, $keyPrefix, $keySuffix, $mode, $params); + $result2 = $this->setExtraFieldValuesFromPost($object, $extrafields, $keyPrefix, $keySuffix, $mode, $params); + + return $result > 0 && $result2 > 0 ? 1 : -1; + } + + /** + * Set all object values of the object from POST + * + * @param CommonObject $object Object handler + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $mode Get the fields infos for the provided mode ('create', 'edit', 'view', 'list') + * @param array $params Other params + * @return int Result <0 if KO, >0 if OK + */ + public function setObjectFieldValuesFromPost(&$object, $keyPrefix = '', $keySuffix = '', $mode = 'view', $params = array()) + { + $fields = $this->getAllObjectFieldsInfos($object, $mode, $params); + + $error = 0; + foreach ($fields as $fieldKey => $fieldInfos) { + $check = true; + $key = $fieldInfos->nameInClass ?? $fieldInfos->key; + if ($fieldInfos->visible) { + $check = $this->verifyPostFieldValue($fieldInfos, $fieldKey, $keyPrefix, $keySuffix); + } + if ($check) { + $object->$key = $this->getPostFieldValue($fieldInfos, $fieldKey, $object->$key, $keyPrefix, $keySuffix); + } + if (!$fieldInfos->visible) { + $check = $this->verifyFieldValue($fieldInfos, $fieldKey, $object->$key); + } + if (!$check) { + $error++; + } + } + + return $error ? -1 : 1; + } + + /** + * Set all extra field values of the object from POST + * + * @param CommonObject $object Object handler + * @param ExtraFields $extrafields Extrafields handler + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $mode Get the fields infos for the provided mode ('create', 'edit', 'view', 'list') + * @param array $params Other params + * @return int Result <0 if KO, >0 if OK + */ + public function setExtraFieldValuesFromPost(&$object, &$extrafields, $keyPrefix = '', $keySuffix = '', $mode = 'view', $params = array()) + { + $fields = $this->getAllExtraFieldsInfos($object, $extrafields, $mode, $params); + + $error = 0; + foreach ($fields as $fieldKey => $fieldInfos) { + $check = true; + $key = 'options_' . ($fieldInfos->nameInClass ?? $fieldInfos->key); + if ($fieldInfos->visible) { + $check = $this->verifyPostFieldValue($fieldInfos, $fieldKey, $keyPrefix, $keySuffix); + } + if ($check) { + $object->array_options[$key] = $this->getPostFieldValue($fieldInfos, $fieldKey, $object->array_options[$key], $keyPrefix, $keySuffix); + } + if (!$fieldInfos->visible) { + $check = $this->verifyFieldValue($fieldInfos, $fieldKey, $object->array_options[$key]); + } + if (!$check) { + $error++; + } + } + + return $error ? -1 : 1; + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of attribute + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return bool + */ + public function verifyPostFieldValue($fieldInfos, $key, $keyPrefix = '', $keySuffix = '') + { + global $hookmanager; + + $result = true; + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 1 || getDolGlobalString('MAIN_ACTIVATE_VALIDATION_RESULT')) { + $parameters = array( + 'fieldInfos' => &$fieldInfos, + 'key' => $key, + 'keyPrefix' => $keyPrefix, + 'keySuffix' => $keySuffix, + ); + + $reshook = $hookmanager->executeHooks('verifyPostFieldValue', $parameters, $this); // Note that $object may have been modified by hook + if ($reshook > 0) { + return (bool) $hookmanager->resPrint; + } + + $this->clearErrors(); + $field = $this->getFieldClass($fieldInfos->type); + if (isset($field)) { + $this->clearFieldError($key); + $result = $field->verifyPostFieldValue($fieldInfos, $key, $keyPrefix, $keySuffix); + if (!$result) { + $this->setFieldError($key, CommonField::$validator->error); + } + } + } + + return $result; + } + + /** + * Verify if the field value is valid + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $value Value to check (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @return bool + */ + public function verifyFieldValue($fieldInfos, $key, $value) + { + global $hookmanager; + + $result = true; + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 1 || getDolGlobalString('MAIN_ACTIVATE_VALIDATION_RESULT')) { + $parameters = array( + 'fieldInfos' => &$fieldInfos, + 'key' => $key, + 'value' => $value, + ); + + $reshook = $hookmanager->executeHooks('verifyFieldValue', $parameters, $this); // Note that $object may have been modified by hook + if ($reshook > 0) { + return (bool) $hookmanager->resPrint; + } + + $this->clearErrors(); + $field = $this->getFieldClass($fieldInfos->type); + if (isset($field)) { + $this->clearFieldError($key); + $result = $field->verifyFieldValue($fieldInfos, $key, $value); + if (!$result) { + $this->setFieldError($key, CommonField::$validator->error); + } + } + } + + return $result; + } + + /** + * Get field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + */ + public function getPostFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + global $hookmanager; + + $value = ''; + $parameters = array( + 'fieldInfos' => &$fieldInfos, + 'key' => $key, + 'value' => &$value, + 'keyPrefix' => $keyPrefix, + 'keySuffix' => $keySuffix, + ); + + $reshook = $hookmanager->executeHooks('getPostFieldValue', $parameters, $this); // Note that $object may have been modified by hook + if ($reshook > 0) { + return $value; + } + + $this->clearErrors(); + $field = $this->getFieldClass($fieldInfos->type); + if (isset($field)) { + $value = $field->getPostFieldValue($fieldInfos, $key, $defaultValue, $keyPrefix, $keySuffix); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Get search field value from GET/POST + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of field + * @param mixed $defaultValue Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return mixed + */ + public function getPostSearchFieldValue($fieldInfos, $key, $defaultValue = null, $keyPrefix = '', $keySuffix = '') + { + global $hookmanager; + + $value = ''; + $parameters = array( + 'fieldInfos' => &$fieldInfos, + 'key' => $key, + 'value' => &$value, + 'keyPrefix' => $keyPrefix, + 'keySuffix' => $keySuffix, + ); + + $reshook = $hookmanager->executeHooks('getPostSearchFieldValue', $parameters, $this); // Note that $object may have been modified by hook + if ($reshook > 0) { + return $value; + } + + $this->clearErrors(); + $field = $this->getFieldClass($fieldInfos->type); + if (isset($field)) { + $value = $field->getPostSearchFieldValue($fieldInfos, $key, $defaultValue, $keyPrefix, $keySuffix); + } else { + $value = $defaultValue; + } + + return $value; + } + + /** + * Return HTML string to put an input search field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of attribute + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @param int<0,1> $noNewButton Force to not show the new button on field that are links to object + * @return string + */ + public function printInputSearchField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '', $noNewButton = 0) + { + global $hookmanager; + + $overwrite_before = ''; + $overwrite_content = ''; + $overwrite_after = ''; + + $parameters = array( + 'fieldInfos' => &$fieldInfos, + 'key' => $key, + 'value' => &$value, + 'keyPrefix' => $keyPrefix, + 'keySuffix' => $keySuffix, + 'moreCss' => $moreCss, + 'moreAttrib' => $moreAttrib, + 'noNewButton' => $noNewButton, + 'overwrite_before' => &$overwrite_before, + 'overwrite_content' => &$overwrite_content, + 'overwrite_after' => &$overwrite_after, + ); + + $hookmanager->executeHooks('printInputSearchField', $parameters, $this); // Note that $this may have been modified by hook + + if (!empty($fieldInfos->computed)) { + return ''; + } + + $out = $overwrite_before; + if (empty($overwrite_content)) { + $this->clearErrors(); + $field = $this->getFieldClass($fieldInfos->type); + if (isset($field)) { + $moreCss = $field->getInputCss($fieldInfos, $moreCss); + + $out .= $field->printInputSearchField($fieldInfos, $key, $value, $keyPrefix, $keySuffix, $moreCss, $moreAttrib); + } else { + $out .= $this->errorsToString(); + } + } else { + $out .= $overwrite_content; + } + $out .= $overwrite_after; + + return $out; + } + + /** + * Return HTML string to put an input field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of attribute + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @param int<0,1> $noNewButton Force to not show the new button on field that are links to object + * @return string + */ + public function printInputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '', $noNewButton = 0) + { + global $hookmanager, $langs; + + $overwrite_before = ''; + $overwrite_content = ''; + $overwrite_after = ''; + + $parameters = array( + 'fieldInfos' => &$fieldInfos, + 'key' => $key, + 'value' => &$value, + 'keyPrefix' => $keyPrefix, + 'keySuffix' => $keySuffix, + 'moreCss' => $moreCss, + 'moreAttrib' => $moreAttrib, + 'noNewButton' => $noNewButton, + 'overwrite_before' => &$overwrite_before, + 'overwrite_content' => &$overwrite_content, + 'overwrite_after' => &$overwrite_after, + ); + + $hookmanager->executeHooks('printInputField', $parameters, $this); // Note that $this may have been modified by hook + + if (!empty($fieldInfos->computed)) { + return '' . $langs->trans("AutomaticallyCalculated") . ''; + } + + if (!$fieldInfos->editable) { + return $this->printOutputField($fieldInfos, $key, $value, $keyPrefix, $keySuffix, $moreCss, $moreAttrib); + } + + // Get validation error + $fieldValidationErrorMsg = $this->getFieldError($key); + + $out = $overwrite_before; + if (empty($overwrite_content)) { + $this->clearErrors(); + $field = $this->getFieldClass($fieldInfos->type); + if (isset($field)) { + $moreCss = $field->getInputCss($fieldInfos, $moreCss); + + // Add validation state class + if (!empty($fieldValidationErrorMsg)) { + $moreCss .= ' --error'; // the -- is use as class state in css : .--error can't be be defined alone it must be define with another class like .my-class.--error or input.--error + } else { + $moreCss .= ' --success'; // the -- is use as class state in css : .--success can't be be defined alone it must be define with another class like .my-class.--success or input.--success + } + + $out .= $field->printInputField($fieldInfos, $key, $value, $keyPrefix, $keySuffix, $moreCss, $moreAttrib); + } else { + $out .= $this->errorsToString(); + } + } else { + $out .= $overwrite_content; + } + if (empty($overwrite_after)) { + // Display error message for field + $out .= $this->getFieldErrorIcon($fieldValidationErrorMsg); + } else { + $out .= $overwrite_after; + } + + return $out; + } + + /** + * Return HTML string to show a field into a page + * + * @param FieldInfos $fieldInfos Properties of the field + * @param string $key Key of attribute + * @param mixed $value Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value, for array type must be array) + * @param string $keyPrefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keySuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $moreCss Value for css to define style/length of field. + * @param string $moreAttrib To add more attributes on html input tag + * @return string + */ + public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '') + { + global $hookmanager; + + $overwrite_before = ''; + $overwrite_content = ''; + $overwrite_after = ''; + + $parameters = array( + 'fieldInfos' => &$fieldInfos, + 'key' => $key, + 'value' => &$value, + 'keyPrefix' => $keyPrefix, + 'keySuffix' => $keySuffix, + 'moreCss' => $moreCss, + 'moreAttrib' => $moreAttrib, + 'overwrite_before' => &$overwrite_before, + 'overwrite_content' => &$overwrite_content, + 'overwrite_after' => &$overwrite_after, + ); + + $hookmanager->executeHooks('printOutputField', $parameters, $this); // Note that $object may have been modified by hook + + $out = $overwrite_before; + if (empty($overwrite_content)) { + $this->clearErrors(); + $field = $this->getFieldClass($fieldInfos->type); + if (isset($field)) { + $moreCss = $field->getInputCss($fieldInfos, $moreCss); + + $out .= $field->printOutputField($fieldInfos, $key, $value, $keyPrefix, $keySuffix, $moreCss, $moreAttrib); + } else { + $out .= $this->errorsToString(); + } + } else { + $out .= $overwrite_content; + } + $out .= $overwrite_after; + + return $out; + } + + /** + * Return HTML string to print separator field + * + * @param string $key Key of attribute + * @param object $object Object + * @param int $colspan Value of colspan to use (it must include the first column with title) + * @param string $display_type "card" for form display, "line" for document line display + * @param string $mode Show output ('view') or input ('create' or 'edit') for field + * @return string HTML code with line for separator + */ + public function printSeparator($key, &$object, $colspan = 2, $display_type = 'card', $mode = 'view') + { + global $conf, $langs; + + // TODO to adapt for field and not extra fields only + $out = ''; + + /*$tagtype = 'tr'; + $tagtype_dyn = 'td'; + + if ($display_type == 'line') { + $tagtype = 'div'; + $tagtype_dyn = 'span'; + $colspan = 0; + } + + $extrafield_param = $this->attributes[$object->table_element]['param'][$key]; + $extrafield_param_list = array(); + if (!empty($extrafield_param) && is_array($extrafield_param)) { + $extrafield_param_list = array_keys($extrafield_param['options']); + } + + // Set $extrafield_collapse_display_value (do we have to collapse/expand the group after the separator) + $extrafield_collapse_display_value = -1; + $expand_display = false; + if (is_array($extrafield_param_list) && count($extrafield_param_list) > 0) { + $extrafield_collapse_display_value = intval($extrafield_param_list[0]); + $expand_display = ((isset($_COOKIE['DOLUSER_COLLAPSE_' . $object->table_element . '_extrafields_' . $key]) || GETPOSTINT('ignorecollapsesetup')) ? (!empty($_COOKIE['DOLUSER_COLLAPSE_' . $object->table_element . '_extrafields_' . $key])) : !($extrafield_collapse_display_value == 2)); + } + $disabledcookiewrite = 0; + if ($mode == 'create') { + // On create mode, force separator group to not be collapsible + $extrafield_collapse_display_value = 1; + $expand_display = true; // We force group to be shown expanded + $disabledcookiewrite = 1; // We keep status of group unchanged into the cookie + } + + $out = '<' . $tagtype . ' id="trextrafieldseparator' . $key . (!empty($object->id) ? '_' . $object->id : '') . '" class="trextrafieldseparator trextrafieldseparator' . $key . (!empty($object->id) ? '_' . $object->id : '') . '">'; + $out .= '<' . $tagtype_dyn . ' ' . (!empty($colspan) ? 'colspan="' . $colspan . '"' : '') . '>'; + // Some js code will be injected here to manage the collapsing of fields + // Output the picto + $out .= ''; + $out .= ' '; + $out .= ''; + $out .= $langs->trans($this->attributes[$object->table_element]['label'][$key]); + $out .= ''; + $out .= ''; + $out .= ''; + + $collapse_group = $key . (!empty($object->id) ? '_' . $object->id : ''); + //$extrafields_collapse_num = $this->attributes[$object->table_element]['pos'][$key].(!empty($object->id)?'_'.$object->id:''); + + if ($extrafield_collapse_display_value == 1 || $extrafield_collapse_display_value == 2) { + // Set the collapse_display status to cookie in priority or if ignorecollapsesetup is 1, if cookie and ignorecollapsesetup not defined, use the setup. + $this->expand_display[$collapse_group] = $expand_display; + + if (!empty($conf->use_javascript_ajax)) { + $out .= '' . "\n"; + $out .= '' . "\n"; + } + } else { + $this->expand_display[$collapse_group] = 1; + }*/ + + return $out; + } +} diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 8260b5a52f3..a5a61b45e34 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -12847,4 +12847,417 @@ class Form return '
    '; } + + /** + * Html for input with label + * + * @param string $type Type of input : button, checkbox, color, email, hidden, month, number, password, radio, range, tel, text, time, url, week + * @param string $name Name + * @param string $value [=''] Value + * @param string $id [=''] Id + * @param string $morecss [=''] Class + * @param string $moreparam [=''] Add attributes (checked, required, etc) + * @param string $label [=''] Label + * @param string $addInputLabel [=''] Add label for input + * @return string Html for input with label + */ + public function inputType($type, $name, $value = '', $id = '', $morecss = '', $moreparam = '', $label = '', $addInputLabel = '') + { + $out = ''; + if ($label != '') { + $out .= '