WIP - create validation method for common object
This commit is contained in:
parent
a7300d01b0
commit
aa94d40ad0
@ -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 array $val Array of properties of field to show
|
||||||
* @param string $key Key of attribute
|
* @param string $fieldKey Key of attribute
|
||||||
* @return int >0 if OK, <0 if KO , 0 no test available.
|
* @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)
|
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
|
// 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->error = ''; // error will be use for form error display so must be clear before
|
||||||
|
|
||||||
if(!isset($val[$fieldKey])){
|
if (!isset($val[$fieldKey])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7310,13 +7311,13 @@ abstract class CommonObject
|
|||||||
$type = $val[$fieldKey]['type'];
|
$type = $val[$fieldKey]['type'];
|
||||||
|
|
||||||
$required = false;
|
$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).
|
// '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;
|
$required = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$maxSize = 0;
|
$maxSize = 0;
|
||||||
|
$minSize = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// PREPARE Elements
|
// PREPARE Elements
|
||||||
@ -7360,52 +7361,98 @@ abstract class CommonObject
|
|||||||
// TEST Value
|
// 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);
|
$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)){
|
if($required && !$validate->isNotEmptyString($fieldValue)){
|
||||||
$this->error = $validate->error;
|
$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)){
|
if(!empty($maxSize) && !$validate->isMaxLength($fieldValue, $maxSize)){
|
||||||
$this->error = $validate->error;
|
$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 (in_array($type, array('date', 'datetime', 'timestamp'))) {
|
||||||
if(!$validate->isTimestamp($fieldValue)){
|
if (!$validate->isTimestamp($fieldValue)) {
|
||||||
$this->error = $validate->error;
|
$this->error = $validate->error;
|
||||||
return -1;
|
return false;
|
||||||
}
|
} else { return true; }
|
||||||
} elseif ($type == 'duration') {
|
} elseif ($type == 'duration') {
|
||||||
// int
|
if(!$validate->isDuration($fieldValue)){
|
||||||
} elseif (in_array($type, array('double', 'real', 'price'))) {
|
$this->error = $validate->error;
|
||||||
|
return false;
|
||||||
|
} else { return true; }
|
||||||
|
}
|
||||||
|
elseif (in_array($type, array('double', 'real', 'price')))
|
||||||
|
{
|
||||||
// is numeric
|
// is numeric
|
||||||
} elseif ($type == 'boolean') {
|
if(!$validate->isDuration($fieldValue)){
|
||||||
// is bool
|
$this->error = $validate->error;
|
||||||
} elseif ($type == 'mail') {
|
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)){
|
if(!$validate->isEmail($fieldValue)){
|
||||||
$this->error = $validate->error;
|
$this->error = $validate->error;
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
} elseif ($type == 'url') {
|
}
|
||||||
|
elseif ($type == 'url')
|
||||||
|
{
|
||||||
if(!$validate->isUrl($fieldValue)){
|
if(!$validate->isUrl($fieldValue)){
|
||||||
$this->error = $validate->error;
|
$this->error = $validate->error;
|
||||||
return -1;
|
return false;
|
||||||
}
|
} else { return true; }
|
||||||
} elseif ($type == 'phone') {
|
}
|
||||||
|
elseif ($type == 'phone')
|
||||||
} elseif ($type == 'select' || $type == 'radio') {
|
{
|
||||||
// isset in list
|
if (!$validate->isPhone($fieldValue)) {
|
||||||
if(!isset($param['options'][$fieldValue])){
|
$this->error = $validate->error;
|
||||||
|
return false;
|
||||||
}
|
} else { return true; }
|
||||||
} elseif ($type == 'sellist' || $type == 'chkbxlst') {
|
}
|
||||||
|
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']);
|
$param_list = array_keys($param['options']);
|
||||||
$InfoFieldList = explode(":", $param_list[0]);
|
$InfoFieldList = explode(":", $param_list[0]);
|
||||||
$value_arr = explode(',', $fieldValue);
|
$value_arr = explode(',', $fieldValue);
|
||||||
@ -7416,63 +7463,25 @@ abstract class CommonObject
|
|||||||
$selectkey = $InfoFieldList[2];
|
$selectkey = $InfoFieldList[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO tester toute les valeur du tableau séparement
|
if(!isInDb($value_arr, $InfoFieldList[0], $selectkey)){
|
||||||
|
$this->error = $validate->error;
|
||||||
$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;
|
return false;
|
||||||
}
|
} else { return true; }
|
||||||
} elseif ($type == 'link') {
|
}
|
||||||
|
elseif ($type == 'link')
|
||||||
// only if something to display (perf)
|
{
|
||||||
if (!empty($fieldValue)) {
|
$param_list = array_keys($param['options']); // $param_list='ObjectName:classPath'
|
||||||
$param_list = array_keys($param['options']); // $param_list='ObjectName:classPath'
|
$InfoFieldList = explode(":", $param_list[0]);
|
||||||
$InfoFieldList = explode(":", $param_list[0]);
|
$classname = $InfoFieldList[0];
|
||||||
$classname = $InfoFieldList[0];
|
$classpath = $InfoFieldList[1];
|
||||||
$classpath = $InfoFieldList[1];
|
if(!$validate->isFetchable($fieldValue, $classname, $classpath)){
|
||||||
if (!empty($classpath)) {
|
$this->error = $validate->error;
|
||||||
dol_include_once($InfoFieldList[1]);
|
return false;
|
||||||
if ($classname && class_exists($classname)) {
|
} else { return true; }
|
||||||
$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;
|
// if no test failled all is ok
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -122,7 +122,22 @@ class Validate
|
|||||||
public function isTimestamp($stamp)
|
public function isTimestamp($stamp)
|
||||||
{
|
{
|
||||||
if (!is_numeric($stamp) && (int)$stamp == $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 false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -191,4 +206,101 @@ class Validate
|
|||||||
return true;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,5 +8,12 @@ RequireValidEmail = Email address is not valid
|
|||||||
RequireMaxLength = Length must be less than %s chars
|
RequireMaxLength = Length must be less than %s chars
|
||||||
RequireMinLength = Length must be more than %s char(s)
|
RequireMinLength = Length must be more than %s char(s)
|
||||||
RequireValidUrl = Require valid URL
|
RequireValidUrl = Require valid URL
|
||||||
RequireValideDate = Require a valid date
|
RequireValidDate = Require a valid date
|
||||||
RequireANotEmptyValue = Is required
|
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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user