From a7300d01b050f8cfb68ec08c2cd1040b71460614 Mon Sep 17 00:00:00 2001 From: ATM john Date: Thu, 3 Jun 2021 09:49:07 +0200 Subject: [PATCH 01/15] WIP - create validation method for common object --- htdocs/core/class/commonobject.class.php | 189 ++++++++++++++++++++++ htdocs/core/class/validate.class.php | 194 +++++++++++++++++++++++ htdocs/langs/en_US/validate.lang | 12 ++ 3 files changed, 395 insertions(+) create mode 100644 htdocs/core/class/validate.class.php create mode 100644 htdocs/langs/en_US/validate.lang diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 3f4b2dd9ee6..12f88fc0a58 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7285,6 +7285,195 @@ abstract class CommonObject return $out; } + /** + * Return validation test for a field + * + * @param array $val Array of properties of field to show + * @param string $key Key of attribute + * @return int >0 if OK, <0 if KO , 0 no test available. + */ + public function validateField($val, $fieldKey, $fieldValue) + { + global $langs; + + if(!class_exists('Validate')){ require_once DOL_DOCUMENT_ROOT . '/core/class/validate.class.php'; } + + // TODO : ask @eldy to know if need to use another error field to separate error msg + $this->error = ''; // error will be use for form error display so must be clear before + + if(!isset($val[$fieldKey])){ + return false; + } + + $param = array(); + $param['options'] = array(); + $type = $val[$fieldKey]['type']; + + $required = false; + if(isset($val[$fieldKey]['notnull']) && $val[$fieldKey]['notnull'] === 1){ + // 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + $required = true; + } + + $maxSize = 0; + + + // + // PREPARE Elements + // + + // Convert var to be able to share same code than showOutputField of extrafields + if (preg_match('/varchar\((\d+)\)/', $type, $reg)) { + $type = 'varchar'; // convert varchar(xx) int varchar + $maxSize = $reg[1]; + } elseif (preg_match('/varchar/', $type)) { + $type = 'varchar'; // convert varchar(xx) int varchar + } + + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { + $type = 'select'; + } + + if (preg_match('/^integer:(.*):(.*)/i', $val['type'], $reg)) { + $type = 'link'; + } + + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { + $param['options'] = $val['arrayofkeyval']; + } + + if (preg_match('/^integer:(.*):(.*)/i', $val['type'], $reg)) { + $type = 'link'; + $param['options'] = array($reg[1].':'.$reg[2]=>$reg[1].':'.$reg[2]); + } elseif (preg_match('/^sellist:(.*):(.*):(.*):(.*)/i', $val['type'], $reg)) { + $param['options'] = array($reg[1].':'.$reg[2].':'.$reg[3].':'.$reg[4] => 'N'); + $type = 'sellist'; + } elseif (preg_match('/^sellist:(.*):(.*):(.*)/i', $val['type'], $reg)) { + $param['options'] = array($reg[1].':'.$reg[2].':'.$reg[3] => 'N'); + $type = 'sellist'; + } elseif (preg_match('/^sellist:(.*):(.*)/i', $val['type'], $reg)) { + $param['options'] = array($reg[1].':'.$reg[2] => 'N'); + $type = 'sellist'; + } + + // + // TEST Value + // + + // Use Validate class to allow external Modules to use data validation part instead of concentrate all test here (factoring) + $validate = new Validate($this->db, $langs); + + + if($required && !$validate->isNotEmptyString($fieldValue)){ + $this->error = $validate->error; + return -1; + } + + + if(!empty($maxSize) && !$validate->isMaxLength($fieldValue, $maxSize)){ + $this->error = $validate->error; + return -1; + } + + + + if (in_array($type, array('date', 'datetime', 'timestamp'))) { + if(!$validate->isTimestamp($fieldValue)){ + $this->error = $validate->error; + return -1; + } + } elseif ($type == 'duration') { + // int + } elseif (in_array($type, array('double', 'real', 'price'))) { + // is numeric + } elseif ($type == 'boolean') { + // is bool + } elseif ($type == 'mail') { + if(!$validate->isEmail($fieldValue)){ + $this->error = $validate->error; + return -1; + } + } elseif ($type == 'url') { + if(!$validate->isUrl($fieldValue)){ + $this->error = $validate->error; + return -1; + } + } elseif ($type == 'phone') { + + } elseif ($type == 'select' || $type == 'radio') { + // isset in list + if(!isset($param['options'][$fieldValue])){ + + } + } elseif ($type == 'sellist' || $type == 'chkbxlst') { + $param_list = array_keys($param['options']); + $InfoFieldList = explode(":", $param_list[0]); + $value_arr = explode(',', $fieldValue); + $value_arr = array_map(array($this->db, 'escape'), $value_arr); + + $selectkey = "rowid"; + if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) { + $selectkey = $InfoFieldList[2]; + } + + // TODO tester toute les valeur du tableau séparement + + $sql = 'SELECT '.$selectkey; + $sql .= ' FROM '.MAIN_DB_PREFIX.$InfoFieldList[0]; + if ($selectkey == 'rowid' && empty($value)) { + $sql .= " WHERE ".$selectkey."=0"; + } else { + $sql .= " WHERE ".$selectkey." IN ('".implode(',',$value_arr)."')"; + } + + dol_syslog(get_class($this).':validateField:$type=sellist', LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + if (empty($num)) { + // error value not found + $this->error = 'error msg'; + return false; + } else { + return true; + } + + } else { + dol_syslog(get_class($this).'::validateField error '.$this->db->lasterror(), LOG_WARNING); + return false; + } + } elseif ($type == 'link') { + + // only if something to display (perf) + if (!empty($fieldValue)) { + $param_list = array_keys($param['options']); // $param_list='ObjectName:classPath' + $InfoFieldList = explode(":", $param_list[0]); + $classname = $InfoFieldList[0]; + $classpath = $InfoFieldList[1]; + if (!empty($classpath)) { + dol_include_once($InfoFieldList[1]); + if ($classname && class_exists($classname)) { + $object = new $classname($this->db); + if($object->fetch($fieldValue)>0){ + return true; + } + $this->error = 'class not found for validation'; + } else { + $this->error = 'Error bad setup of extrafield'; + } + return false; + } else { + $this->error = 'Error bad setup of extrafield'; + return false; + } + } + else { + // TODO vérifier si requis + } + } + + return 0; + } /** * Function to show lines of extrafields with output datas. diff --git a/htdocs/core/class/validate.class.php b/htdocs/core/class/validate.class.php new file mode 100644 index 00000000000..fa02018118b --- /dev/null +++ b/htdocs/core/class/validate.class.php @@ -0,0 +1,194 @@ + + * + * 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 + * 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/validate.class.php + * \ingroup core + * \brief File for Utils class + */ + + +/** + * Class toolbox to validate values + */ +class Validate +{ + + /** + * @var DoliDb Database handler (result of a new DoliDB) + */ + public $db; + + /** + * @var Translate $outputLang + */ + public $outputLang; + + /** + * @var string Error string + * @see $errors + */ + public $error; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + * @param Translate $outputLang + */ + public function __construct($db,$outputLang = false) + { + global $langs; + + if ($outputLang) { + $this->outputLang = $langs; + } else { + $this->outputLang = $outputLang; + } + + $outputLang->load('validate'); + + $this->db = $db; + } + + /** + * Use to clear errors msg or other ghost vars + */ + protected function clear() + { + $this->error = ''; + } + + /** + * Use to clear errors msg or other ghost vars + */ + protected function setError($errMsg) + { + $this->error = ''; + } + + /** + * Check for e-mail validity + * + * @param string $email e-mail address to validate + * @param int $maxLength + * @return boolean Validity is ok or not + */ + public function isEmail($email, $maxLength = false) + { + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + $this->error = $this->outputLang->trans('RequireValidEmail'); + return false; + } + return true; + } + + /** + * Check for price validity + * + * @param string $price Price to validate + * @return boolean Validity is ok or not + */ + public function isPrice($price) + { + if (!preg_match('/^[0-9]{1,10}(\.[0-9]{1,9})?$/ui', $price)) { + $this->error = $this->outputLang->trans('RequireValidValue'); + return false; + } + return true; + } + + /** + * Check for timestamp validity + * + * @param string|int $stamp timestamp to validate + * @return boolean Validity is ok or not + */ + public function isTimestamp($stamp) + { + if (!is_numeric($stamp) && (int)$stamp == $stamp) { + $this->error = $this->outputLang->trans('RequireValideDate'); + return false; + } + return true; + } + + /** + * Check for string max length validity + * + * @param string $string to validate + * @param int $length max length + * @return boolean Validity is ok or not + */ + public function isMaxLength($string, $length) + { + if (strlen($string) > $length) { + $this->error = $this->outputLang->trans('RequireMaxLength', $length); + return false; + } + return true; + } + + /** + * Check for string not empty + * + * @param string $string to validate + * @param int $length max length + * @return boolean Validity is ok or not + */ + public function isNotEmptyString($string) + { + if (!strlen($string)) { + $this->error = $this->outputLang->trans('RequireANotEmptyValue'); + return false; + } + return true; + } + + /** + * Check for string min length validity + * + * @param string $string to validate + * @param int $length max length + * @return boolean Validity is ok or not + */ + public function isMinLength($string, $length) + { + if (!strlen($string) < $length) { + $this->error = $this->outputLang->trans('RequireMinLength', $length); + return false; + } + return true; + } + + /** + * Check url validity + * + * @param string $url to validate + * @return boolean Validity is ok or not + */ + public function isUrl($url) + { + if (!filter_var($url, FILTER_VALIDATE_URL)) { + $this->error = $this->outputLang->trans('RequireValidUrl'); + return false; + } + return true; + } + +} diff --git a/htdocs/langs/en_US/validate.lang b/htdocs/langs/en_US/validate.lang new file mode 100644 index 00000000000..1464805b853 --- /dev/null +++ b/htdocs/langs/en_US/validate.lang @@ -0,0 +1,12 @@ +# Dolibarr language file - Source file is en_US - users +RequireValidValue = Value not valid +RequireAtLeastXString = Requires at least % character(s) +RequireXStringMax = Requires % character(s) max +RequireAtLeastXDigits = Requires at least % digit(s) +RequireXDigitsMax = Requires % digit(s) max +RequireValidEmail = Email address is not valid +RequireMaxLength = Length must be less than %s chars +RequireMinLength = Length must be more than %s char(s) +RequireValidUrl = Require valid URL +RequireValideDate = Require a valid date +RequireANotEmptyValue = Is required From aa94d40ad0ef4325c44b39df8bbb5e6b1dfd73e8 Mon Sep 17 00:00:00 2001 From: ATM john Date: Sun, 6 Jun 2021 21:12:03 +0200 Subject: [PATCH 02/15] WIP - create validation method for common object --- htdocs/core/class/commonobject.class.php | 179 ++++++++++++----------- htdocs/core/class/validate.class.php | 114 ++++++++++++++- htdocs/langs/en_US/validate.lang | 9 +- 3 files changed, 215 insertions(+), 87 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 12f88fc0a58..ae5f0d33216 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7286,11 +7286,12 @@ abstract class CommonObject } /** - * Return validation test for a field + * Return validation test result for a field * - * @param array $val Array of properties of field to show - * @param string $key Key of attribute - * @return int >0 if OK, <0 if KO , 0 no test available. + * @param array $val Array of properties of field to show + * @param string $fieldKey Key of attribute + * @param string $fieldValue value of attribute + * @return bool return false if fail true on success, see $this->error for error message */ public function validateField($val, $fieldKey, $fieldValue) { @@ -7301,7 +7302,7 @@ abstract class CommonObject // TODO : ask @eldy to know if need to use another error field to separate error msg $this->error = ''; // error will be use for form error display so must be clear before - if(!isset($val[$fieldKey])){ + if (!isset($val[$fieldKey])) { return false; } @@ -7310,13 +7311,13 @@ abstract class CommonObject $type = $val[$fieldKey]['type']; $required = false; - if(isset($val[$fieldKey]['notnull']) && $val[$fieldKey]['notnull'] === 1){ + if (isset($val[$fieldKey]['notnull']) && $val[$fieldKey]['notnull'] === 1) { // 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). $required = true; } $maxSize = 0; - + $minSize = 0; // // PREPARE Elements @@ -7360,52 +7361,98 @@ abstract class CommonObject // TEST Value // - // Use Validate class to allow external Modules to use data validation part instead of concentrate all test here (factoring) + // Use Validate class to allow external Modules to use data validation part instead of concentrate all test here (factoring) or just for reuse $validate = new Validate($this->db, $langs); + // little trick : to perform tests with good performances sort tests by quick to low + + // + // COMMON TESTS + // + + // Required test and empty value if($required && !$validate->isNotEmptyString($fieldValue)){ $this->error = $validate->error; - return -1; + return false; + } + elseif (!$required && !$validate->isNotEmptyString($fieldValue)) { + // if no value sent and the field is not mandatory, no need to perform tests + return true; } - + // MAX Size test if(!empty($maxSize) && !$validate->isMaxLength($fieldValue, $maxSize)){ $this->error = $validate->error; - return -1; + return false; } + // MIN Size test + if(!empty($minSize) && !$validate->isMinLength($fieldValue, $minSize)){ + $this->error = $validate->error; + return false; + } + // + // TESTS for TYPE + // if (in_array($type, array('date', 'datetime', 'timestamp'))) { - if(!$validate->isTimestamp($fieldValue)){ + if (!$validate->isTimestamp($fieldValue)) { $this->error = $validate->error; - return -1; - } + return false; + } else { return true; } } elseif ($type == 'duration') { - // int - } elseif (in_array($type, array('double', 'real', 'price'))) { + if(!$validate->isDuration($fieldValue)){ + $this->error = $validate->error; + return false; + } else { return true; } + } + elseif (in_array($type, array('double', 'real', 'price'))) + { // is numeric - } elseif ($type == 'boolean') { - // is bool - } elseif ($type == 'mail') { + if(!$validate->isDuration($fieldValue)){ + $this->error = $validate->error; + return false; + } else { return true; } + } + elseif ($type == 'boolean') + { + if(!$validate->isBool($fieldValue)){ + $this->error = $validate->error; + return false; + } else { return true; } + } + elseif ($type == 'mail') + { if(!$validate->isEmail($fieldValue)){ $this->error = $validate->error; - return -1; + return false; } - } elseif ($type == 'url') { + } + elseif ($type == 'url') + { if(!$validate->isUrl($fieldValue)){ $this->error = $validate->error; - return -1; - } - } elseif ($type == 'phone') { - - } elseif ($type == 'select' || $type == 'radio') { - // isset in list - if(!isset($param['options'][$fieldValue])){ - - } - } elseif ($type == 'sellist' || $type == 'chkbxlst') { + return false; + } else { return true; } + } + elseif ($type == 'phone') + { + if (!$validate->isPhone($fieldValue)) { + $this->error = $validate->error; + return false; + } else { return true; } + } + elseif ($type == 'select' || $type == 'radio') + { + if (!isset($param['options'][$fieldValue])) { + $this->error = $langs->trans('RequireValidValue'); + return false; + } else { return true; } + } + elseif ($type == 'sellist' || $type == 'chkbxlst') + { $param_list = array_keys($param['options']); $InfoFieldList = explode(":", $param_list[0]); $value_arr = explode(',', $fieldValue); @@ -7416,63 +7463,25 @@ abstract class CommonObject $selectkey = $InfoFieldList[2]; } - // TODO tester toute les valeur du tableau séparement - - $sql = 'SELECT '.$selectkey; - $sql .= ' FROM '.MAIN_DB_PREFIX.$InfoFieldList[0]; - if ($selectkey == 'rowid' && empty($value)) { - $sql .= " WHERE ".$selectkey."=0"; - } else { - $sql .= " WHERE ".$selectkey." IN ('".implode(',',$value_arr)."')"; - } - - dol_syslog(get_class($this).':validateField:$type=sellist', LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) { - $num = $this->db->num_rows($resql); - if (empty($num)) { - // error value not found - $this->error = 'error msg'; - return false; - } else { - return true; - } - - } else { - dol_syslog(get_class($this).'::validateField error '.$this->db->lasterror(), LOG_WARNING); + if(!isInDb($value_arr, $InfoFieldList[0], $selectkey)){ + $this->error = $validate->error; return false; - } - } elseif ($type == 'link') { - - // only if something to display (perf) - if (!empty($fieldValue)) { - $param_list = array_keys($param['options']); // $param_list='ObjectName:classPath' - $InfoFieldList = explode(":", $param_list[0]); - $classname = $InfoFieldList[0]; - $classpath = $InfoFieldList[1]; - if (!empty($classpath)) { - dol_include_once($InfoFieldList[1]); - if ($classname && class_exists($classname)) { - $object = new $classname($this->db); - if($object->fetch($fieldValue)>0){ - return true; - } - $this->error = 'class not found for validation'; - } else { - $this->error = 'Error bad setup of extrafield'; - } - return false; - } else { - $this->error = 'Error bad setup of extrafield'; - return false; - } - } - else { - // TODO vérifier si requis - } + } else { return true; } + } + elseif ($type == 'link') + { + $param_list = array_keys($param['options']); // $param_list='ObjectName:classPath' + $InfoFieldList = explode(":", $param_list[0]); + $classname = $InfoFieldList[0]; + $classpath = $InfoFieldList[1]; + if(!$validate->isFetchable($fieldValue, $classname, $classpath)){ + $this->error = $validate->error; + return false; + } else { return true; } } - return 0; + // if no test failled all is ok + return true; } /** diff --git a/htdocs/core/class/validate.class.php b/htdocs/core/class/validate.class.php index fa02018118b..ac01ce76531 100644 --- a/htdocs/core/class/validate.class.php +++ b/htdocs/core/class/validate.class.php @@ -122,7 +122,22 @@ class Validate public function isTimestamp($stamp) { if (!is_numeric($stamp) && (int)$stamp == $stamp) { - $this->error = $this->outputLang->trans('RequireValideDate'); + $this->error = $this->outputLang->trans('RequireValidDate'); + return false; + } + return true; + } + + /** + * Check for phone validity + * + * @param string $phone Phone string to validate + * @return boolean Validity is ok or not + */ + public function isPhone($phone) + { + if (!preg_match('/^[+0-9. ()-]*$/ui', $phone)) { + $this->error = $this->outputLang->trans('RequireValidPhone'); return false; } return true; @@ -191,4 +206,101 @@ class Validate return true; } + /** + * Check Duration validity + * + * @param string $duration to validate + * @return boolean Validity is ok or not + */ + public function isDuration($duration) + { + if (!is_int($duration) && $duration >= 0) { + $this->error = $this->outputLang->trans('RequireValidDuration'); + return false; + } + return true; + } + + /** + * Check for boolean validity + * + * @param boolean $bool Boolean to validate + * @return boolean Validity is ok or not + */ + public function isBool($bool) + { + if(!(is_null($bool) || is_bool($bool) || preg_match('/^[0|1]{1}$/ui', $bool))){ + $this->error = $this->outputLang->trans('RequireValidBool'); + return false; + } + return true; + } + + /** + * Check for all values in db + * + * @param array $values Boolean to validate + * @param string $table the db table name without MAIN_DB_PREFIX + * @param string $col the target col + * @return boolean Validity is ok or not + * @throws Exception + */ + public function isInDb($values, $table, $col) + { + if (!is_array($values)) { + $value_arr = array($values); + } else { + $value_arr = $values; + } + + if (!count($value_arr)) { + $this->error = $this->outputLang->trans('RequireValue'); + return false; + } + + foreach ($value_arr as $val){ + $val = $this->db->escape($val); + $sql = 'SELECT ' . $col . ' FROM ' . MAIN_DB_PREFIX . $table . " WHERE " . $col ." = '" . $val . "'"; // nore quick than count(*) to check existing of a row + $resql = $this->db->getRow($sql); + if ($resql) { + continue; + } else { + $this->error = $this->outputLang->trans('RequireValidExistingElement'); + return false; + } + } + + return true; + } + + /** + * Check for all values in db + * + * @param array $values Boolean to validate + * @param string $classname the class name + * @param string $classpath the class path + * @return boolean Validity is ok or not + * @throws Exception + */ + public function isFetchable($values, $classname, $classpath) + { + if (!empty($classpath)) { + if (dol_include_once($classpath)) { + if ($classname && class_exists($classname)) { + /** @var CommonObject $object */ + $object = new $classname($this->db); + + if (!is_callable(array($object, 'fetch')) || !is_callable(array($object, 'isExistingObject'))) { + $this->error = $this->outputLang->trans('BadSetupOfFieldFetchNotCallable'); + return false; + } + + if (!empty($object->table_element) && $object->isExistingObject($object->table_element, $values)) { + return true; + } else { $this->error = $this->outputLang->trans('RequireValidExistingElement'); } + } else { $this->error = $this->outputLang->trans('BadSetupOfFieldClassNotFoundForValidation'); } + } else { $this->error = $this->outputLang->trans('BadSetupOfFieldFileNotFound'); } + } else { $this->error = $this->outputLang->trans('BadSetupOfField'); } + return false; + } } diff --git a/htdocs/langs/en_US/validate.lang b/htdocs/langs/en_US/validate.lang index 1464805b853..bd25b6c0c74 100644 --- a/htdocs/langs/en_US/validate.lang +++ b/htdocs/langs/en_US/validate.lang @@ -8,5 +8,12 @@ RequireValidEmail = Email address is not valid RequireMaxLength = Length must be less than %s chars RequireMinLength = Length must be more than %s char(s) RequireValidUrl = Require valid URL -RequireValideDate = Require a valid date +RequireValidDate = Require a valid date RequireANotEmptyValue = Is required +RequireValidDuration = Require a valid duration +RequireValidExistingElement = Require an existing value +RequireValidBool = Require a valid boolean +BadSetupOfField = Error bad setup of field +BadSetupOfFieldClassNotFoundForValidation = Error bad setup of field : Class not found for validation +BadSetupOfFieldFileNotFound = Error bad setup of field : File not found for inclusion +BadSetupOfFieldFetchNotCallable = Error bad setup of field : Fetch not callable on class From f1b1dcd1b145af430a62141e013990dbeb28d795 Mon Sep 17 00:00:00 2001 From: ATM john Date: Sun, 6 Jun 2021 21:53:17 +0200 Subject: [PATCH 03/15] WIP - create validation method for common object --- htdocs/core/class/commonobject.class.php | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ae5f0d33216..f3426608c55 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -6376,9 +6376,10 @@ abstract class CommonObject * @param string $keyprefix Suffix string to add into name and id of field (can be used to avoid duplicate names) * @param string|int $morecss Value for css to define style/length of field. May also be a numeric. * @param int $nonewbutton Force to not show the new button on field that are links to object + * @param bool $displayValidationResult Display validation results messages for fields, set it to true after form sended to display user mistakes * @return string */ - public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0) + public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0, $displayValidationResult = false) { global $conf, $langs, $form; @@ -6391,6 +6392,25 @@ abstract class CommonObject $val = $this->fields[$key]; } + // This is en experimental validation output TODO : remove this deactivation line + if ($conf->global->MAIN_FEATURES_LEVEL < 2 && empty($conf->global->MAIN_ACTIVATE_VALIDATION_RESULT)) { $displayValidationResult = false; } + + // Validation tests and output + $fieldValidation = 0; // 0 not tested, -1 error, 1 success + $fieldValidationErrorMesg = ''; + $validationClass = ''; + if ($displayValidationResult) { + if (!$this->validateField($val, $key, $value)) { + $validationClass = ' --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 + $fieldValidation = -1; + $fieldValidationErrorMesg = $this->error; + } else { + $validationClass = ' --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 + $fieldValidation = 1; + } + } + + $out = ''; $type = ''; $isDependList=0; From 801f6cab2d3bb86554a610fba27b92a649420ebb Mon Sep 17 00:00:00 2001 From: ATM john Date: Sun, 6 Jun 2021 21:58:59 +0200 Subject: [PATCH 04/15] WIP - create validation method for common object --- htdocs/core/class/validate.class.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/core/class/validate.class.php b/htdocs/core/class/validate.class.php index ac01ce76531..3f94da5dbe0 100644 --- a/htdocs/core/class/validate.class.php +++ b/htdocs/core/class/validate.class.php @@ -259,8 +259,7 @@ class Validate } foreach ($value_arr as $val){ - $val = $this->db->escape($val); - $sql = 'SELECT ' . $col . ' FROM ' . MAIN_DB_PREFIX . $table . " WHERE " . $col ." = '" . $val . "'"; // nore quick than count(*) to check existing of a row + $sql = 'SELECT ' . $col . ' FROM ' . MAIN_DB_PREFIX . $table . " WHERE " . $col ." = '" . $this->db->escape($val) . "'"; // nore quick than count(*) to check existing of a row $resql = $this->db->getRow($sql); if ($resql) { continue; From 578dc9adde74c913962083eb4e129ffec0ed0fc9 Mon Sep 17 00:00:00 2001 From: ATM john Date: Sat, 12 Jun 2021 12:58:20 +0200 Subject: [PATCH 05/15] WIP - create validation method for common object --- htdocs/core/actions_addupdatedelete.inc.php | 9 +++ htdocs/core/class/commonobject.class.php | 65 +++++++++++++++---- .../template/class/myobject.class.php | 2 +- 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index f871ed73de8..6c03839a996 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -105,6 +105,15 @@ if ($action == 'add' && !empty($permissiontoadd)) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv($val['label'])), null, 'errors'); } + + // Validation of fields values + if ($conf->global->MAIN_FEATURE_LEVEL >= 2 || !empty($conf->global->MAIN_USE_COMMON_VALIDATION)) { + if (!$error && !empty($val['validate']) && is_callable(array($object, 'validateField'))) { + if (!$object->validateField($object->fields, $key, $value)) { + $error++; + } + } + } } // Fill array 'array_options' with data from add form diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index f3426608c55..39eeae90fc2 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -123,6 +123,10 @@ abstract class CommonObject */ protected $table_ref_field = ''; + /** + * @var array $validateFieldsErrors to store error results of ->validateField() + */ + public $validateFieldsErrors = array(); // Following vars are used by some objects only. We keep this property here in CommonObject to be able to provide common method using them. @@ -7305,6 +7309,40 @@ abstract class CommonObject return $out; } + /** + * clear validation message result for a field + * + * @param string $fieldKey Key of attribute to clear + */ + public function clearFieldError($fieldKey) + { + $this->error = ''; + unset($this->validateFieldsErrors[$fieldKey]); + } + + /** + * set validation error message a field + * + * @param string $fieldKey Key of attribute + */ + public function setFieldError($fieldKey, $msg = '') + { + $this->error = $this->validateFieldsErrors[$fieldKey] = $msg; + } + + /** + * get field error message + * + * @param string $fieldKey Key of attribute + */ + public function getFieldError($fieldKey) + { + if (!empty($this->validateFieldsErrors[$fieldKey])) { + return $this->validateFieldsErrors[$fieldKey]; + } + return ''; + } + /** * Return validation test result for a field * @@ -7319,8 +7357,7 @@ abstract class CommonObject if(!class_exists('Validate')){ require_once DOL_DOCUMENT_ROOT . '/core/class/validate.class.php'; } - // TODO : ask @eldy to know if need to use another error field to separate error msg - $this->error = ''; // error will be use for form error display so must be clear before + $this->clearFieldError($fieldKey); if (!isset($val[$fieldKey])) { return false; @@ -7393,7 +7430,7 @@ abstract class CommonObject // Required test and empty value if($required && !$validate->isNotEmptyString($fieldValue)){ - $this->error = $validate->error; + $this->setFieldError($fieldKey, $validate->error); return false; } elseif (!$required && !$validate->isNotEmptyString($fieldValue)) { @@ -7403,13 +7440,13 @@ abstract class CommonObject // MAX Size test if(!empty($maxSize) && !$validate->isMaxLength($fieldValue, $maxSize)){ - $this->error = $validate->error; + $this->setFieldError($fieldKey, $validate->error); return false; } // MIN Size test if(!empty($minSize) && !$validate->isMinLength($fieldValue, $minSize)){ - $this->error = $validate->error; + $this->setFieldError($fieldKey, $validate->error); return false; } @@ -7419,12 +7456,12 @@ abstract class CommonObject if (in_array($type, array('date', 'datetime', 'timestamp'))) { if (!$validate->isTimestamp($fieldValue)) { - $this->error = $validate->error; + $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } } elseif ($type == 'duration') { if(!$validate->isDuration($fieldValue)){ - $this->error = $validate->error; + $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } } @@ -7432,35 +7469,35 @@ abstract class CommonObject { // is numeric if(!$validate->isDuration($fieldValue)){ - $this->error = $validate->error; + $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } } elseif ($type == 'boolean') { if(!$validate->isBool($fieldValue)){ - $this->error = $validate->error; + $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } } elseif ($type == 'mail') { if(!$validate->isEmail($fieldValue)){ - $this->error = $validate->error; + $this->setFieldError($fieldKey, $validate->error); return false; } } elseif ($type == 'url') { if(!$validate->isUrl($fieldValue)){ - $this->error = $validate->error; + $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } } elseif ($type == 'phone') { if (!$validate->isPhone($fieldValue)) { - $this->error = $validate->error; + $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } } @@ -7484,7 +7521,7 @@ abstract class CommonObject } if(!isInDb($value_arr, $InfoFieldList[0], $selectkey)){ - $this->error = $validate->error; + $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } } @@ -7495,7 +7532,7 @@ abstract class CommonObject $classname = $InfoFieldList[0]; $classpath = $InfoFieldList[1]; if(!$validate->isFetchable($fieldValue, $classname, $classpath)){ - $this->error = $validate->error; + $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } } diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index e69c5bc333d..be8736f9d49 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -91,7 +91,7 @@ class MyObject extends CommonObject * 'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar' * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. * 'comment' is not used. You can store here any text of your choice. It is not used by application. - * + * 'validate' is 1 if need to validate with $this->validateField() * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. */ From 43ecba2e6304496caa6b499c596bbc74634d509a Mon Sep 17 00:00:00 2001 From: ATM john Date: Sat, 12 Jun 2021 14:16:40 +0200 Subject: [PATCH 06/15] WIP - create validation method for common object --- htdocs/core/actions_addupdatedelete.inc.php | 11 ++++++++- htdocs/core/class/commonobject.class.php | 25 ++++++++++++++------- htdocs/core/lib/functions.lib.php | 17 ++++++++++++++ 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index 6c03839a996..d2d22d74e3c 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -107,7 +107,7 @@ if ($action == 'add' && !empty($permissiontoadd)) { } // Validation of fields values - if ($conf->global->MAIN_FEATURE_LEVEL >= 2 || !empty($conf->global->MAIN_USE_COMMON_VALIDATION)) { + if ($conf->global->MAIN_FEATURE_LEVEL >= 2 || !empty($conf->global->MAIN_ACTIVATE_VALIDATION_RESULT)) { if (!$error && !empty($val['validate']) && is_callable(array($object, 'validateField'))) { if (!$object->validateField($object->fields, $key, $value)) { $error++; @@ -213,6 +213,15 @@ if ($action == 'update' && !empty($permissiontoadd)) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv($val['label'])), null, 'errors'); } + + // Validation of fields values + if ($conf->global->MAIN_FEATURE_LEVEL >= 2 || !empty($conf->global->MAIN_ACTIVATE_VALIDATION_RESULT)) { + if (!$error && !empty($val['validate']) && is_callable(array($object, 'validateField'))) { + if (!$object->validateField($object->fields, $key, $value)) { + $error++; + } + } + } } // Fill array 'array_options' with data from add form diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 39eeae90fc2..cfba42e0adf 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -6381,9 +6381,10 @@ abstract class CommonObject * @param string|int $morecss Value for css to define style/length of field. May also be a numeric. * @param int $nonewbutton Force to not show the new button on field that are links to object * @param bool $displayValidationResult Display validation results messages for fields, set it to true after form sended to display user mistakes + * @param string $mode 1=Used for search filters * @return string */ - public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0, $displayValidationResult = false) + public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0, $mode = 0) { global $conf, $langs, $form; @@ -6400,17 +6401,14 @@ abstract class CommonObject if ($conf->global->MAIN_FEATURES_LEVEL < 2 && empty($conf->global->MAIN_ACTIVATE_VALIDATION_RESULT)) { $displayValidationResult = false; } // Validation tests and output - $fieldValidation = 0; // 0 not tested, -1 error, 1 success - $fieldValidationErrorMesg = ''; + $fieldValidationErrorMsg = ''; $validationClass = ''; - if ($displayValidationResult) { - if (!$this->validateField($val, $key, $value)) { + if($mode == 0){ + $fieldValidationErrorMsg = $this->getFieldError($key); + if (!empty($fieldValidationErrorMsg)) { $validationClass = ' --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 - $fieldValidation = -1; - $fieldValidationErrorMesg = $this->error; } else { $validationClass = ' --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 - $fieldValidation = 1; } } @@ -6506,6 +6504,11 @@ abstract class CommonObject } } + // Add validation state class + if (!empty($validationClass)) { + $morecss.= ' '.$validationClass; + } + if (in_array($type, array('date'))) { $tmp = explode(',', $size); $newsize = $tmp[0]; @@ -6971,6 +6974,12 @@ abstract class CommonObject if ($type == 'date') $out.=' (YYYY-MM-DD)'; elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)'; */ + + // Display error message for field + if ($mode == 0 && !empty($fieldValidationErrorMsg) && function_exists('getFieldErrorIcon')) { + $out .= ' '.getFieldErrorIcon($fieldValidationErrorMsg); + } + return $out; } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 61a3869fe1a..5dd500a26a0 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -9753,6 +9753,23 @@ function dolGetButtonTitleSeparator($moreClass = "") return ''; } +/** + * get field error icon + * + * @param string $fieldValidationErrorMsg + */ +function getFieldErrorIcon($fieldValidationErrorMsg) +{ + $out = ''; + if (!empty($fieldValidationErrorMesg)) { + $out.= ''; // role alert is used for accessibility + $out.= ''; // For accessibility icon is separated and aria-hidden + $out.= ''; + } + + return $out; +} + /** * Function dolGetButtonTitle : this kind of buttons are used in title in list * From 23765bf459474e30fb213c4086099fb6178cef41 Mon Sep 17 00:00:00 2001 From: ATM john Date: Mon, 14 Jun 2021 20:59:46 +0200 Subject: [PATCH 07/15] WIP - create validation method for common object --- htdocs/core/class/commonobject.class.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index cfba42e0adf..9e9333b8962 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -6380,8 +6380,7 @@ abstract class CommonObject * @param string $keyprefix Suffix string to add into name and id of field (can be used to avoid duplicate names) * @param string|int $morecss Value for css to define style/length of field. May also be a numeric. * @param int $nonewbutton Force to not show the new button on field that are links to object - * @param bool $displayValidationResult Display validation results messages for fields, set it to true after form sended to display user mistakes - * @param string $mode 1=Used for search filters + * @param int $mode 1=Used for search filters * @return string */ public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0, $mode = 0) @@ -6397,9 +6396,6 @@ abstract class CommonObject $val = $this->fields[$key]; } - // This is en experimental validation output TODO : remove this deactivation line - if ($conf->global->MAIN_FEATURES_LEVEL < 2 && empty($conf->global->MAIN_ACTIVATE_VALIDATION_RESULT)) { $displayValidationResult = false; } - // Validation tests and output $fieldValidationErrorMsg = ''; $validationClass = ''; From be367c589f971f81e6010d5f527c605db3d5f8a0 Mon Sep 17 00:00:00 2001 From: ATM john Date: Mon, 14 Jun 2021 21:12:48 +0200 Subject: [PATCH 08/15] WIP - create validation method for common object --- htdocs/core/class/commonobject.class.php | 65 ++++++++++-------------- 1 file changed, 26 insertions(+), 39 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 9e9333b8962..2b83e324ab3 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -6399,7 +6399,7 @@ abstract class CommonObject // Validation tests and output $fieldValidationErrorMsg = ''; $validationClass = ''; - if($mode == 0){ + if ($mode == 0) { $fieldValidationErrorMsg = $this->getFieldError($key); if (!empty($fieldValidationErrorMsg)) { $validationClass = ' --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 @@ -7318,6 +7318,7 @@ abstract class CommonObject * clear validation message result for a field * * @param string $fieldKey Key of attribute to clear + * @return null */ public function clearFieldError($fieldKey) { @@ -7328,7 +7329,9 @@ abstract class CommonObject /** * set validation error message a field * - * @param string $fieldKey Key of attribute + * @param string $fieldKey Key of attribute + * @param string $msg the field error message + * @return null */ public function setFieldError($fieldKey, $msg = '') { @@ -7339,6 +7342,7 @@ abstract class CommonObject * get field error message * * @param string $fieldKey Key of attribute + * @return string */ public function getFieldError($fieldKey) { @@ -7360,7 +7364,7 @@ abstract class CommonObject { global $langs; - if(!class_exists('Validate')){ require_once DOL_DOCUMENT_ROOT . '/core/class/validate.class.php'; } + if (!class_exists('Validate')) { require_once DOL_DOCUMENT_ROOT . '/core/class/validate.class.php'; } $this->clearFieldError($fieldKey); @@ -7434,23 +7438,22 @@ abstract class CommonObject // // Required test and empty value - if($required && !$validate->isNotEmptyString($fieldValue)){ + if ($required && !$validate->isNotEmptyString($fieldValue)) { $this->setFieldError($fieldKey, $validate->error); return false; - } - elseif (!$required && !$validate->isNotEmptyString($fieldValue)) { + } elseif (!$required && !$validate->isNotEmptyString($fieldValue)) { // if no value sent and the field is not mandatory, no need to perform tests return true; } // MAX Size test - if(!empty($maxSize) && !$validate->isMaxLength($fieldValue, $maxSize)){ + if (!empty($maxSize) && !$validate->isMaxLength($fieldValue, $maxSize)) { $this->setFieldError($fieldKey, $validate->error); return false; } // MIN Size test - if(!empty($minSize) && !$validate->isMinLength($fieldValue, $minSize)){ + if (!empty($minSize) && !$validate->isMinLength($fieldValue, $minSize)) { $this->setFieldError($fieldKey, $validate->error); return false; } @@ -7465,56 +7468,42 @@ abstract class CommonObject return false; } else { return true; } } elseif ($type == 'duration') { - if(!$validate->isDuration($fieldValue)){ + if (!$validate->isDuration($fieldValue)) { $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } - } - elseif (in_array($type, array('double', 'real', 'price'))) - { + } elseif (in_array($type, array('double', 'real', 'price'))) { // is numeric - if(!$validate->isDuration($fieldValue)){ + if (!$validate->isDuration($fieldValue)) { $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } - } - elseif ($type == 'boolean') - { - if(!$validate->isBool($fieldValue)){ + } elseif ($type == 'boolean') { + if (!$validate->isBool($fieldValue)) { $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } - } - elseif ($type == 'mail') - { - if(!$validate->isEmail($fieldValue)){ + } elseif ($type == 'mail') { + if (!$validate->isEmail($fieldValue)) { $this->setFieldError($fieldKey, $validate->error); return false; } - } - elseif ($type == 'url') - { - if(!$validate->isUrl($fieldValue)){ + } elseif ($type == 'url') { + if (!$validate->isUrl($fieldValue)) { $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } - } - elseif ($type == 'phone') - { + } elseif ($type == 'phone') { if (!$validate->isPhone($fieldValue)) { $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } - } - elseif ($type == 'select' || $type == 'radio') - { + } elseif ($type == 'select' || $type == 'radio') { if (!isset($param['options'][$fieldValue])) { $this->error = $langs->trans('RequireValidValue'); return false; } else { return true; } - } - elseif ($type == 'sellist' || $type == 'chkbxlst') - { + } elseif ($type == 'sellist' || $type == 'chkbxlst') { $param_list = array_keys($param['options']); $InfoFieldList = explode(":", $param_list[0]); $value_arr = explode(',', $fieldValue); @@ -7525,18 +7514,16 @@ abstract class CommonObject $selectkey = $InfoFieldList[2]; } - if(!isInDb($value_arr, $InfoFieldList[0], $selectkey)){ + if (!isInDb($value_arr, $InfoFieldList[0], $selectkey)) { $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } - } - elseif ($type == 'link') - { + } elseif ($type == 'link') { $param_list = array_keys($param['options']); // $param_list='ObjectName:classPath' $InfoFieldList = explode(":", $param_list[0]); $classname = $InfoFieldList[0]; $classpath = $InfoFieldList[1]; - if(!$validate->isFetchable($fieldValue, $classname, $classpath)){ + if (!$validate->isFetchable($fieldValue, $classname, $classpath)) { $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } From 82f195dc3057f6eef8fce4b4659f9a3b8c9a0f8d Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 14 Jun 2021 19:15:53 +0000 Subject: [PATCH 09/15] Fixing style errors. --- htdocs/core/class/validate.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/validate.class.php b/htdocs/core/class/validate.class.php index 3f94da5dbe0..2b9d98ae5e0 100644 --- a/htdocs/core/class/validate.class.php +++ b/htdocs/core/class/validate.class.php @@ -51,7 +51,7 @@ class Validate * @param DoliDB $db Database handler * @param Translate $outputLang */ - public function __construct($db,$outputLang = false) + public function __construct($db, $outputLang = false) { global $langs; @@ -121,7 +121,7 @@ class Validate */ public function isTimestamp($stamp) { - if (!is_numeric($stamp) && (int)$stamp == $stamp) { + if (!is_numeric($stamp) && (int) $stamp == $stamp) { $this->error = $this->outputLang->trans('RequireValidDate'); return false; } @@ -229,7 +229,7 @@ class Validate */ public function isBool($bool) { - if(!(is_null($bool) || is_bool($bool) || preg_match('/^[0|1]{1}$/ui', $bool))){ + if (!(is_null($bool) || is_bool($bool) || preg_match('/^[0|1]{1}$/ui', $bool))) { $this->error = $this->outputLang->trans('RequireValidBool'); return false; } @@ -258,7 +258,7 @@ class Validate return false; } - foreach ($value_arr as $val){ + foreach ($value_arr as $val) { $sql = 'SELECT ' . $col . ' FROM ' . MAIN_DB_PREFIX . $table . " WHERE " . $col ." = '" . $this->db->escape($val) . "'"; // nore quick than count(*) to check existing of a row $resql = $this->db->getRow($sql); if ($resql) { From 4d043b713cf7c44c34890037592b380f659dd99d Mon Sep 17 00:00:00 2001 From: ATM john Date: Mon, 21 Jun 2021 21:54:03 +0200 Subject: [PATCH 10/15] WIP - create validation method for common object --- htdocs/core/class/commonobject.class.php | 22 +++++++++---------- htdocs/core/lib/functions.lib.php | 7 +++--- .../template/class/myobject.class.php | 20 ++++++++--------- htdocs/theme/eldy/global.inc.php | 8 ++++--- 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 2b83e324ab3..b9cc03893fd 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -6380,10 +6380,9 @@ abstract class CommonObject * @param string $keyprefix Suffix string to add into name and id of field (can be used to avoid duplicate names) * @param string|int $morecss Value for css to define style/length of field. May also be a numeric. * @param int $nonewbutton Force to not show the new button on field that are links to object - * @param int $mode 1=Used for search filters * @return string */ - public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0, $mode = 0) + public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0) { global $conf, $langs, $form; @@ -6399,16 +6398,13 @@ abstract class CommonObject // Validation tests and output $fieldValidationErrorMsg = ''; $validationClass = ''; - if ($mode == 0) { - $fieldValidationErrorMsg = $this->getFieldError($key); - if (!empty($fieldValidationErrorMsg)) { - $validationClass = ' --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 { - $validationClass = ' --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 - } + $fieldValidationErrorMsg = $this->getFieldError($key); + if (!empty($fieldValidationErrorMsg)) { + $validationClass = ' --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 { + $validationClass = ' --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 = ''; $type = ''; $isDependList=0; @@ -6972,7 +6968,7 @@ abstract class CommonObject */ // Display error message for field - if ($mode == 0 && !empty($fieldValidationErrorMsg) && function_exists('getFieldErrorIcon')) { + if (!empty($fieldValidationErrorMsg) && function_exists('getFieldErrorIcon')) { $out .= ' '.getFieldErrorIcon($fieldValidationErrorMsg); } @@ -7335,6 +7331,9 @@ abstract class CommonObject */ public function setFieldError($fieldKey, $msg = '') { + global $langs; + if (empty($msg)) { $msg = $langs->trans("UnknowError"); } + $this->error = $this->validateFieldsErrors[$fieldKey] = $msg; } @@ -7369,6 +7368,7 @@ abstract class CommonObject $this->clearFieldError($fieldKey); if (!isset($val[$fieldKey])) { + $this->setFieldError($fieldKey, $langs->trans('FieldNotFoundInObject')); return false; } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 5dd500a26a0..2c5d2144180 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -9756,13 +9756,14 @@ function dolGetButtonTitleSeparator($moreClass = "") /** * get field error icon * - * @param string $fieldValidationErrorMsg + * @param string $fieldValidationErrorMsg message to add in tooltip + * @return string html output */ function getFieldErrorIcon($fieldValidationErrorMsg) { $out = ''; - if (!empty($fieldValidationErrorMesg)) { - $out.= ''; // role alert is used for accessibility + if (!empty($fieldValidationErrorMsg)) { + $out.= ''; // role alert is used for accessibility $out.= ''; // For accessibility icon is separated and aria-hidden $out.= ''; } diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index be8736f9d49..118c60275f1 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -101,16 +101,16 @@ class MyObject extends CommonObject */ public $fields = array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'noteditable'=>1, 'notnull'=> 1, 'index'=>1, 'position'=>1, 'comment'=>'Id', 'css'=>'left'), - 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'noteditable'=>0, 'default'=>'', 'notnull'=> 1, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'noteditable'=>0, 'default'=>'', 'notnull'=> 1, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object', 'validate'=>1), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=> 1, 'default'=>1, 'index'=>1, 'position'=>20), - 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>'Help text', 'showoncombobox'=>1), - 'amount' => array('type'=>'price', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'default'=>'null', 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for amount'), - 'qty' => array('type'=>'real', 'label'=>'Qty', 'enabled'=>1, 'visible'=>1, 'default'=>'0', 'position'=>45, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for quantity', 'css'=>'maxwidth75imp'), - 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'picto'=>'company', 'label'=>'ThirdParty', 'visible'=> 1, 'enabled'=>1, 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'LinkToThirparty'), - 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>1, 'visible'=>-1, 'position'=>52, 'notnull'=>-1, 'index'=>1), - 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>3, 'position'=>60), - 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61), - 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>'Help text', 'showoncombobox'=>1, 'validate'=>1), + 'amount' => array('type'=>'price', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'default'=>'null', 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for amount', 'validate'=>1), + 'qty' => array('type'=>'real', 'label'=>'Qty', 'enabled'=>1, 'visible'=>1, 'default'=>'0', 'position'=>45, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for quantity', 'css'=>'maxwidth75imp', 'validate'=>1), + 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'picto'=>'company', 'label'=>'ThirdParty', 'visible'=> 1, 'enabled'=>1, 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'LinkToThirparty', 'validate'=>1), + 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>1, 'visible'=>-1, 'position'=>52, 'notnull'=>-1, 'index'=>1, 'validate'=>1), + 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>3, 'position'=>60, 'validate'=>1), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61, 'validate'=>1), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62, 'validate'=>1), 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 1, 'position'=>500), 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 0, 'position'=>501), //'date_validation ' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>502), @@ -120,7 +120,7 @@ class MyObject extends CommonObject 'last_main_doc' => array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>0, 'notnull'=>0, 'position'=>600), 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'index'=>0, 'position'=>1000), 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'notnull'=>-1, 'position'=>1010), - 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=> 1, 'default'=>0, 'index'=>1, 'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 9=>'Canceled')), + 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=> 1, 'default'=>0, 'index'=>1, 'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 9=>'Canceled'), 'validate'=>1), ); /** diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 4468c36a7da..c14289ba4b3 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -234,10 +234,12 @@ input.button.massactionconfirmed { margin: 4px; } -input:invalid, select:invalid { +input:invalid, select:invalid, input.--error , select.--error { border-color: #ea1212; } +.field-error-icon { color: #ea1212; !important; } + /* Focus definitions must be after standard definition */ textarea:focus { border: 1px solid #aaa !important; @@ -433,7 +435,7 @@ input.pageplusone { transform: scale(-1, 1); } -select:invalid { +select:invalid, select.--error { color: gray; } input:disabled, textarea:disabled, select[disabled='disabled'] @@ -2076,7 +2078,7 @@ span.widthpictotitle.pictotitle { vertical-align: middle; margin-top: -3px } -.pictowarning, .pictoerror, .pictopreview { +.pictowarning, .picto.error, .pictopreview { padding-: 3px; } .pictowarning { From a9a7315ce1037dc732794d4376fc40879883d09f Mon Sep 17 00:00:00 2001 From: ATM john Date: Sun, 11 Jul 2021 13:30:30 +0200 Subject: [PATCH 11/15] WIP - create validation method for common object --- .../template/class/myobject.class.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index eb263ee5541..f0ecc5e4987 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -102,15 +102,15 @@ class MyObject extends CommonObject public $fields = array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'noteditable'=>1, 'notnull'=> 1, 'index'=>1, 'position'=>1, 'comment'=>'Id', 'css'=>'left'), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=> 1, 'default'=>1, 'index'=>1, 'position'=>10), - 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'noteditable'=>0, 'default'=>'', 'notnull'=> 1, 'showoncombobox'=>1, 'index'=>1, 'position'=>20, 'searchall'=>1, 'comment'=>'Reference of object'), - 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>'Help text', 'showoncombobox'=>2), - 'amount' => array('type'=>'price', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'default'=>'null', 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for amount'), - 'qty' => array('type'=>'real', 'label'=>'Qty', 'enabled'=>1, 'visible'=>1, 'default'=>'0', 'position'=>45, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for quantity', 'css'=>'maxwidth75imp'), - 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'picto'=>'company', 'label'=>'ThirdParty', 'visible'=> 1, 'enabled'=>1, 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'LinkToThirparty'), - 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>1, 'visible'=>-1, 'position'=>52, 'notnull'=>-1, 'index'=>1), - 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>3, 'position'=>60), - 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61), - 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'noteditable'=>0, 'default'=>'', 'notnull'=> 1, 'showoncombobox'=>1, 'index'=>1, 'position'=>20, 'searchall'=>1, 'comment'=>'Reference of object', 'validate'=>1), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>'Help text', 'showoncombobox'=>2, 'validate'=>1), + 'amount' => array('type'=>'price', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'default'=>'null', 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for amount', 'validate'=>1), + 'qty' => array('type'=>'real', 'label'=>'Qty', 'enabled'=>1, 'visible'=>1, 'default'=>'0', 'position'=>45, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for quantity', 'css'=>'maxwidth75imp', 'validate'=>1), + 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'picto'=>'company', 'label'=>'ThirdParty', 'visible'=> 1, 'enabled'=>1, 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'LinkToThirparty', 'validate'=>1), + 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>1, 'visible'=>-1, 'position'=>52, 'notnull'=>-1, 'index'=>1, 'validate'=>1), + 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>3, 'position'=>60, 'validate'=>1), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61, 'validate'=>1), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62, 'validate'=>1), 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 1, 'position'=>500), 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 0, 'position'=>501), //'date_validation ' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>502), From dc3f960ce8d1e7900350f0393e126adfc065a1ac Mon Sep 17 00:00:00 2001 From: ATM john Date: Sun, 11 Jul 2021 14:05:26 +0200 Subject: [PATCH 12/15] Add validate to module builder --- htdocs/core/lib/modulebuilder.lib.php | 3 +++ htdocs/langs/en_US/modulebuilder.lang | 3 ++- htdocs/modulebuilder/index.php | 12 +++++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php index 27a4ea7a9ab..a5589679b50 100644 --- a/htdocs/core/lib/modulebuilder.lib.php +++ b/htdocs/core/lib/modulebuilder.lib.php @@ -176,6 +176,9 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = } $texttoinsert .= "),"; } + if ($val['validate']) { + $texttoinsert .= " 'validate'=>'".$val['validate']."',"; + } if ($val['comment']) { $texttoinsert .= " 'comment'=>\"".preg_replace('/"/', '', $val['comment'])."\""; } diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 7ba539d3bd4..5d6b51d5fe4 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -143,4 +143,5 @@ AsciiToHtmlConverter=Ascii to HTML converter AsciiToPdfConverter=Ascii to PDF converter TableNotEmptyDropCanceled=Table not empty. Drop has been canceled. ModuleBuilderNotAllowed=The module builder is available but not allowed to your user. -ImportExportProfiles=Import and export profiles \ No newline at end of file +ImportExportProfiles=Import and export profiles +ValidateModBuilderDesc=Put 1 if this field need to be validated with $this->validateField() or 0 if validation required diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index f8ca876eafc..0a05266b6ff 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -1303,7 +1303,8 @@ if ($dirins && $action == 'addproperty' && empty($cancel) && !empty($module) && 'visible'=>GETPOST('propvisible', 'int'), 'enabled'=>GETPOST('propenabled', 'int'), 'position'=>GETPOST('propposition', 'int'), 'notnull'=>GETPOST('propnotnull', 'int'), 'index'=>GETPOST('propindex', 'int'), 'searchall'=>GETPOST('propsearchall', 'int'), 'isameasure'=>GETPOST('propisameasure', 'int'), 'comment'=>GETPOST('propcomment', 'alpha'), 'help'=>GETPOST('prophelp', 'alpha'), - 'css'=>GETPOST('propcss', 'aZ09'), 'cssview'=>GETPOST('propcssview', 'aZ09'), 'csslist'=>GETPOST('propcsslist', 'aZ09') + 'css'=>GETPOST('propcss', 'aZ09'), 'cssview'=>GETPOST('propcssview', 'aZ09'), 'csslist'=>GETPOST('propcsslist', 'aZ09'), + 'validate' => GETPOST('propvalidate', 'int') ); if (!empty($addfieldentry['arrayofkeyval']) && !is_array($addfieldentry['arrayofkeyval'])) { @@ -2680,6 +2681,7 @@ if ($module == 'initmodule') { print ''.$langs->trans("KeyForTooltip").''; print ''.$langs->trans("ShowOnCombobox").''; //print ''.$langs->trans("Disabled").''; + print ''.$form->textwithpicto($langs->trans("Validate"), $langs->trans("ValidateModBuilderDesc")).''; print ''.$langs->trans("Comment").''; print ''; print ''; @@ -2712,6 +2714,7 @@ if ($module == 'initmodule') { print ''; print ''; //print ''; + print ''; print ''; print ''; print ''; @@ -2753,6 +2756,7 @@ if ($module == 'initmodule') { $prophelp = $propval['help']; $propshowoncombobox = $propval['showoncombobox']; //$propdisabled=$propval['disabled']; + $propvalidate = $propval['validate']; $propcomment = $propval['comment']; print ''; @@ -2823,6 +2827,9 @@ if ($module == 'initmodule') { print ''; print ''; print ''; + print ''; + print ''; + print ''; print ''; print ''; print ''; @@ -2888,6 +2895,9 @@ if ($module == 'initmodule') { /*print ''; print $propdisabled?$propdisabled:''; print '';*/ + print ''; + print $propvalidate ? dol_escape_htmltag($propvalidate) : ''; + print ''; print ''; print ''; print dol_escape_htmltag($propcomment); From 19ab5ce4201fccd6ec3a815e960abd341fd3ffeb Mon Sep 17 00:00:00 2001 From: ATM john Date: Sun, 11 Jul 2021 14:13:24 +0200 Subject: [PATCH 13/15] Fix comments --- htdocs/core/class/validate.class.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/validate.class.php b/htdocs/core/class/validate.class.php index 2b9d98ae5e0..e0fae76703d 100644 --- a/htdocs/core/class/validate.class.php +++ b/htdocs/core/class/validate.class.php @@ -49,7 +49,8 @@ class Validate * Constructor * * @param DoliDB $db Database handler - * @param Translate $outputLang + * @param Translate $outputLang output lang for error + * @return null */ public function __construct($db, $outputLang = false) { @@ -68,6 +69,7 @@ class Validate /** * Use to clear errors msg or other ghost vars + * @return null */ protected function clear() { @@ -76,6 +78,9 @@ class Validate /** * Use to clear errors msg or other ghost vars + * + * @param string $errMsg your error message + * @return null */ protected function setError($errMsg) { @@ -86,7 +91,7 @@ class Validate * Check for e-mail validity * * @param string $email e-mail address to validate - * @param int $maxLength + * @param int $maxLength string max length * @return boolean Validity is ok or not */ public function isEmail($email, $maxLength = false) @@ -163,7 +168,6 @@ class Validate * Check for string not empty * * @param string $string to validate - * @param int $length max length * @return boolean Validity is ok or not */ public function isNotEmptyString($string) From 7ad1738944c6bd0aac0b1a208204fd70f1dea4b8 Mon Sep 17 00:00:00 2001 From: ATM john Date: Sun, 11 Jul 2021 15:58:34 +0200 Subject: [PATCH 14/15] Fix setError --- htdocs/core/class/validate.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/validate.class.php b/htdocs/core/class/validate.class.php index e0fae76703d..1738034545d 100644 --- a/htdocs/core/class/validate.class.php +++ b/htdocs/core/class/validate.class.php @@ -84,7 +84,7 @@ class Validate */ protected function setError($errMsg) { - $this->error = ''; + $this->error = $errMsg; } /** From dafb3b5029daf3529b7adc461b90059bdc6f4d08 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 17 Aug 2021 19:41:42 +0200 Subject: [PATCH 15/15] Update global.inc.php --- htdocs/theme/eldy/global.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 200007f6878..311f6a2e584 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -2099,7 +2099,7 @@ span.widthpictotitle.pictotitle { vertical-align: middle; margin-top: -3px } -.pictowarning, .picto.error, .pictopreview { +.pictowarning, .pictoerror, .pictopreview, .picto.error { padding-: 3px; } .pictowarning {