Commit 0f2d60c4 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Refactored sanitize functionality: Form save, form update and client are now...

Refactored sanitize functionality: Form save, form update and client are now handled with the same regexp. Form save and update use the same code to sanatize. SANITIZE names are now equal in FormEditor and in Store. New class SANITIZE_ALL_MIN_MAX_DATE.

OnArray.php: moved inputCheckPatternArray() to Sanatize.
Sanatize.php: complete rewrote of sanitize(). Everything is regexp based now.
FillStore.php: validateValue() removed, use of Sanitize::sanitize instead.
Store.php: adjusted change of Sanitize:sanitize signature.
AbstractBuildForm.php: defined class global variable $inputCheckPattern and initialize them during construct(). Variables, submitted by POST, are now correctly sanatized according their FormElement definition. getInputCheckPattern() adjusted to new/changed SANITIZE definitions.
Constants.php: added SANTIZE_ALLOW_: MIN_MAX, MIN_MAX_DATE, EMAIL, PATTERN, SANITIZE_EXCEPTION, SANITIZE_EMPTY_STRING
Save.php: use of Sanitize::sanitize instead of validateValue()
formEditor.sql: order of FormElement.checkType changed to 'most used first'.
parent b31fb9eb
...@@ -37,6 +37,7 @@ abstract class AbstractBuildForm { ...@@ -37,6 +37,7 @@ abstract class AbstractBuildForm {
protected $wrap = array(); protected $wrap = array();
protected $symbol = array(); protected $symbol = array();
protected $showDebugInfo = false; protected $showDebugInfo = false;
protected $inputCheckPattern = array();
// protected $feDivClass = array(); // Wrap FormElements in <div class="$feDivClass[type]"> // protected $feDivClass = array(); // Wrap FormElements in <div class="$feDivClass[type]">
...@@ -103,7 +104,7 @@ abstract class AbstractBuildForm { ...@@ -103,7 +104,7 @@ abstract class AbstractBuildForm {
$this->symbol[SYMBOL_NEW] = "<span class='glyphicon glyphicon-plus'></span>"; $this->symbol[SYMBOL_NEW] = "<span class='glyphicon glyphicon-plus'></span>";
$this->symbol[SYMBOL_DELETE] = "<span class='glyphicon glyphicon-trash'></span>"; $this->symbol[SYMBOL_DELETE] = "<span class='glyphicon glyphicon-trash'></span>";
$this->inputCheckPattern = OnArray::inputCheckPatternArray(); $this->inputCheckPattern = Sanitize::inputCheckPatternArray();
} }
abstract public function fillWrap(); abstract public function fillWrap();
...@@ -341,7 +342,7 @@ abstract class AbstractBuildForm { ...@@ -341,7 +342,7 @@ abstract class AbstractBuildForm {
$formElement = $evaluate->parseArray($fe, $debugStack); $formElement = $evaluate->parseArray($fe, $debugStack);
// Get default value // Get default value
$value = ($formElement['value'] === '') ? $this->store->getVar($formElement['name']) : $formElement['value']; $value = ($formElement['value'] === '') ? $this->store->getVar($formElement['name'], STORE_USE_DEFAULT, $formElement['checkType']) : $formElement['value'];
$htmlFormElementId = HelperFormElement::buildFormElementId($formElement['name'], $recordId); $htmlFormElementId = HelperFormElement::buildFormElementId($formElement['name'], $recordId);
...@@ -548,14 +549,15 @@ abstract class AbstractBuildForm { ...@@ -548,14 +549,15 @@ abstract class AbstractBuildForm {
/** /**
* Construct HTML Input attribute for Client Validation: * Construct HTML Input attribute for Client Validation:
* *
* type data predefined * type data result
* ------- ----------------------- ------------------------------------------------------------------------------- * ------- ----------------------- -------------------------------------------------------------------------------
* min|max <min value>|<max value> min="%s"|max="%s" * min|max <min value>|<max value> min="$attrData[0]"|max="$attrData[1]"
* pattern <regexp> pattern="%s" * pattern <regexp> pattern="$data"
* digit - pattern="^[0-9]*$" * digit - pattern="^[0-9]*$"
* email - pattern="^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$" * email - pattern="^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$"
* alnumx -
* *
* For 'min|max' and 'pattern' the 'data' will be injected in the attribute string via '%s'. * For 'min/max' and 'pattern' the 'data' will be injected in the attribute string via '%s'.
* *
* @param $type * @param $type
* @param $data * @param $data
...@@ -563,22 +565,35 @@ abstract class AbstractBuildForm { ...@@ -563,22 +565,35 @@ abstract class AbstractBuildForm {
* @throws \qfq\UserException * @throws \qfq\UserException
*/ */
private function getInputCheckPattern($type, $data) { private function getInputCheckPattern($type, $data) {
$attribute = '';
if ($type === '') { if ($type === '') {
return ''; return '';
} }
$attribute = ''; switch ($type) {
case SANITIZE_ALLOW_MIN_MAX:
case SANITIZE_ALLOW_MIN_MAX_DATE:
$arrData = explode("|", $data);
if (count($arrData) != 2 || $arrData[0] == '' || $arrData[1] == '')
throw new UserException("Missing MIN|MAX values", ERROR_MISSING_MIN_MAX);
$arrAttr = explode("|", $this->inputCheckPattern[$type]); $attribute = 'min="' . $arrData[0] . '" ';
$arrData = explode("|", $data); $attribute .= 'max="' . $arrData[1] . '" ';
break;
for ($ii = 0; $ii < count($arrAttr); $ii++) { case SANITIZE_ALLOW_PATTERN:
if ($arrAttr[$ii]) { $attribute = 'pattern="' . $data . '" ';
if (!isset($arrData[$ii])) break;
throw new UserException("Missing MIN|MAX values", ERROR_MISSING_MIN_MAX);
$attribute .= str_replace('%s', trim($arrData[$ii]), $arrAttr[$ii]) . ' '; case SANITIZE_ALLOW_ALL:
} break;
default:
$attribute = 'pattern="' . $this->inputCheckPattern[$type] . '" ';
break;
} }
return $attribute; return $attribute;
} }
......
...@@ -43,9 +43,16 @@ const SQL_FORM_ELEMENT_SIMPLE_ALL_CONTAINER = "SELECT fe.id, fe.name, fe.type, f ...@@ -43,9 +43,16 @@ const SQL_FORM_ELEMENT_SIMPLE_ALL_CONTAINER = "SELECT fe.id, fe.name, fe.type, f
// SANITIZE Classifier // SANITIZE Classifier
const SANITIZE_ALLOW_ALNUMX = "alnumx"; const SANITIZE_ALLOW_ALNUMX = "alnumx";
const SANITIZE_ALLOW_DIGIT = "digit"; const SANITIZE_ALLOW_DIGIT = "digit";
const SANITIZE_ALLOW_MIN_MAX = "min|max";
const SANITIZE_ALLOW_MIN_MAX_DATE = "min|max date";
const SANITIZE_ALLOW_EMAIL = "email";
const SANITIZE_ALLOW_PATTERN = "pattern";
const SANITIZE_ALLOW_ALL = "all"; const SANITIZE_ALLOW_ALL = "all";
const SANITIZE_DEFAULT = SANITIZE_ALLOW_DIGIT; const SANITIZE_DEFAULT = SANITIZE_ALLOW_DIGIT;
const SANATIZE_EXCEPTION = 'exception';
const SANATIZE_EMPTY_STRING = 'empty string';
// Index wrap setup table // Index wrap setup table
const WRAP_SETUP_TITLE = 'title'; const WRAP_SETUP_TITLE = 'title';
const WRAP_SETUP_ELEMENT = 'element'; const WRAP_SETUP_ELEMENT = 'element';
......
...@@ -123,7 +123,7 @@ class Save { ...@@ -123,7 +123,7 @@ class Save {
$clientValues[$clientFieldName] = implode(',', $clientValues[$clientFieldName]); $clientValues[$clientFieldName] = implode(',', $clientValues[$clientFieldName]);
} }
$newValues[$column] = $this->validateValue($formElement, $clientValues[$clientFieldName]); $newValues[$column] = Sanitize::sanitize($clientValues[$clientFieldName], $formElement['checkType'], $formElement['checkPattern'], SANATIZE_EXCEPTION);
} }
} }
...@@ -145,75 +145,6 @@ class Save { ...@@ -145,75 +145,6 @@ class Save {
return false; return false;
} }
/**
* Check $value against given checkType/pattern. Throws an UserException if check fails.
*
* @param $formElement
* @param $value
* @return string
* @throws CodeException
* @throws UserException
*/
public function validateValue($formElement, $value) {
//TODO: Mit Klasse FillStoreForm sollte diese Funktion hier ueberfluessig sein.
$pattern = '';
$minMax = array();
$this->store->setVar(SYSTEM_FORM_ELEMENT, $formElement['name'], STORE_SYSTEM);
switch ($formElement['checkType']) {
case 'min|max':
$valueCompare = $value;
$minMax = explode('|', $formElement['checkPattern']);
if ($minMax[0] === '' || $minMax[1] === '') {
$this->store->setVar(SYSTEM_FORM_ELEMENT_MESSAGE, 'Missing definition of value for min or max.', STORE_SYSTEM);
throw new UserException('Missing definition of value for min or max.', ERROR_MISSING_MIN_MAX);
}
$errorText = "Value '$value' is smaller than min '$minMax[0]' or bigger than max '$minMax[1]'.";
// Date/Time: convert in object to make a comparison.
if (preg_match('date|time', $formElement['type']) === 1) {
$valueCompare = date_create($value);
$minMax[0] = date_create($minMax[0]);
$minMax[1] = date_create($minMax[1]);
}
if ($minMax[0] <= $valueCompare && $valueCompare <= $minMax[1])
return $value;
$this->store->setVar(SYSTEM_FORM_ELEMENT_MESSAGE, $errorText, STORE_SYSTEM);
throw new UserException($errorText, ERROR_MIN_MAX_VIOLATION);
break;
case 'pattern':
$pattern = $formElement['checkPattern'];
break;
case 'number':
case 'email':
$arr = OnArray::inputCheckPatternArray();
$htmlPatternAttribute = $arr[$formElement['checkType']];
// remove 'pattern="' and closing ".
$pattern = substr($htmlPatternAttribute, 9, strlen($htmlPatternAttribute) - 9 - 1);
break;
case '': // no checktype specified.
return $value;
default:
throw new CodeException("Unknown checkType: " . $formElement['checkType'], ERROR_UNKNOWN_CHECKTYPE);
}
if (preg_match($pattern, $value) === 1)
return $value;
$errorText = "Value $value violates checkrule " . $formElement['checkType'] . " with pattern '$pattern'.";
$this->store->setVar(SYSTEM_FORM_ELEMENT_MESSAGE, $errorText, STORE_SYSTEM);
throw new UserException($errorText, ERROR_PATTERN_VIOLATION);
}
/** /**
* Insert new record in table $this->formSpec['tableName']. * Insert new record in table $this->formSpec['tableName'].
* *
......
...@@ -33,7 +33,7 @@ class OnArray { ...@@ -33,7 +33,7 @@ class OnArray {
$dataString = ''; $dataString = '';
foreach ($dataArray as $key => $value) { foreach ($dataArray as $key => $value) {
if(is_array($value)) { if (is_array($value)) {
$value = self::toString($value); $value = self::toString($value);
} }
...@@ -97,18 +97,6 @@ class OnArray { ...@@ -97,18 +97,6 @@ class OnArray {
return $result; return $result;
} }
/**
* @return array
*/
public static function inputCheckPatternArray() {
return [
'min|max' => 'min="%s"|max="%s"',
'pattern' => 'pattern="%s"',
'number' => 'pattern="^[0-9]*$"',
'email' => 'pattern="^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$"'
];
}
/** /**
* Converts a onedimensional array by using htmlentities on all elements * Converts a onedimensional array by using htmlentities on all elements
* *
......
...@@ -19,44 +19,111 @@ require_once(__DIR__ . '/../../qfq/Constants.php'); ...@@ -19,44 +19,111 @@ require_once(__DIR__ . '/../../qfq/Constants.php');
*/ */
class Sanitize { class Sanitize {
private function __construct() { private function __construct() {
// Class should never be instantiated // Class should never be instantiated
} }
/** /**
* Sanitize: check value by sanitize class. Return verified value or empty string if failed. * Check $value against given checkType/pattern. If check succeed, returns values.
* If check fails, depending on $mode, throws an UserException or return an empty string.
* *
* @param string $value - value to check * @param string $value value to check
* @param string $sanitizeClass - class used to check * @param string $sanatizeClass SANITIZE_ALLOW_*
* @return string - if check failed: empty string, if check is ok: value * @param string $patternOrRange Pattern as regexp or MIN|MAX values
* @throws CodeException * @param string $mode SANATIZE_EXCEPTION | SANATIZE_EMPTY_STRING
* @return string
* @throws UserException
* @throws \qfq\CodeException
*/ */
public static function sanitize($value, $sanitizeClass = SANITIZE_DEFAULT) { public static function sanitize($value, $sanatizeClass = SANITIZE_DEFAULT, $patternOrRange = '', $mode = SANATIZE_EMPTY_STRING) {
$pattern = '';
$minMax = array();
$valueCompare = '';
$errorText = "Value $value violates checkrule " . $sanatizeClass . " with pattern '$pattern'.";
$errorCode = 0;
switch ($sanitizeClass) { // Prepare MIN|MAX
case SANITIZE_DEFAULT: switch ($sanatizeClass) {
case SANITIZE_ALLOW_DIGIT: case SANITIZE_ALLOW_MIN_MAX:
if (!is_numeric($value)) { $minMax = explode('|', $patternOrRange);
$value = ''; $valueCompare = $value;
break;
case SANITIZE_ALLOW_MIN_MAX_DATE:
$minMax = explode('|', $patternOrRange);
$valueCompare = date_create($value);
$minMax[0] = date_create($minMax[0]);
$minMax[1] = date_create($minMax[1]);
break;
default:
break;
}
// Prepare Check
switch ($sanatizeClass) {
case SANITIZE_ALLOW_MIN_MAX:
case SANITIZE_ALLOW_MIN_MAX_DATE:
if ($minMax[0] === '' || $minMax[1] === '') {
throw new UserException('Missing definition of value for min or max.', ERROR_MISSING_MIN_MAX);
} }
$errorText = "Value '$value' is smaller than min '$minMax[0]' or bigger than max '$minMax[1]'.";
if ($minMax[0] <= $valueCompare && $valueCompare <= $minMax[1])
return $value;
$errorCode = ERROR_MIN_MAX_VIOLATION;
break; break;
case SANITIZE_ALLOW_ALNUMX: case SANITIZE_ALLOW_PATTERN:
// replace ALNUMX valid characters, which are not part of ctype_alnum, by valid ctype_alnum characters, to fake ctype_alnum $pattern = $patternOrRange;
// definetely forbidden: ' " \ % $
if (!ctype_alnum(str_replace(array('@', '-', '_', '.', ',', ';', ' ', '/', '(', ')'), 'a', $value)))
$value = '';
break; break;
case SANITIZE_ALLOW_ALL: case SANITIZE_ALLOW_DIGIT:
case SANITIZE_ALLOW_EMAIL:
case SANITIZE_ALLOW_ALNUMX:
$arr = self::inputCheckPatternArray();
$pattern = $arr[$sanatizeClass];
break; break;
case SANITIZE_ALLOW_ALL: // no checktype specified.
return $value;
default: default:
throw new CodeException("Sanitize class '$sanitizeClass' unknown. Used to sanitize GET/POST Variable.", ERROR_UNKNOW_SANITIZE_CLASS); throw new CodeException("Unknown checkType: " . $sanatizeClass, ERROR_UNKNOWN_CHECKTYPE);
break; }
// No error until here: do a final check
if ($errorCode == 0) {
if (preg_match("/$pattern/", $value) === 1)
return $value;
else
$errorCode = ERROR_PATTERN_VIOLATION;
} }
return ($value); if ($mode === SANATIZE_EXCEPTION) {
throw new UserException($errorText, $errorCode);
}
// check failed: return empty string
return '';
}
/**
* @return array
*/
public static function inputCheckPatternArray() {
return [
SANITIZE_ALLOW_ALNUMX => '^(@|-|_|\.|,|;|:| |\/|\(|\)|[[:alnum:]])*$',
SANITIZE_ALLOW_DIGIT => '^[\d]*$',
SANITIZE_ALLOW_EMAIL => '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$',
SANITIZE_ALLOW_MIN_MAX => '',
SANITIZE_ALLOW_MIN_MAX_DATE => '',
SANITIZE_ALLOW_PATTERN => '',
SANITIZE_ALLOW_ALL => '.*'
];
} }
} }
\ No newline at end of file
...@@ -111,7 +111,8 @@ class FillStoreForm { ...@@ -111,7 +111,8 @@ class FillStoreForm {
$clientValues[$clientFieldName] = implode(',', $clientValues[$clientFieldName]); $clientValues[$clientFieldName] = implode(',', $clientValues[$clientFieldName]);
} }
$newValues[$formElement['name']] = $this->validateValue($formElement, $clientValues[$clientFieldName]); // $newValues[$formElement['name']] = $this->validateValue($formElement, $clientValues[$clientFieldName]);
$newValues[$formElement['name']] = Sanitize::sanitize($clientValues[$clientFieldName], $formElement['checkType'], $formElement['checkPattern'], SANATIZE_EXCEPTION);
} }
} }
...@@ -119,71 +120,4 @@ class FillStoreForm { ...@@ -119,71 +120,4 @@ class FillStoreForm {
$this->store->setVarArray($newValues, STORE_FORM, true); $this->store->setVarArray($newValues, STORE_FORM, true);
} }
/**
* Check $value against given checkType/pattern. Throws an UserException if check fails.
*
* @param $formElement
* @param $value
* @return string
* @throws CodeException
* @throws UserException
*/
public function validateValue($formElement, $value) {
$pattern = '';
$minMax = array();
$this->store->setVar(SYSTEM_FORM_ELEMENT, $formElement['name'], STORE_SYSTEM);
switch ($formElement['checkType']) {
case 'min|max':
$valueCompare = $value;
$minMax = explode('|', $formElement['checkPattern']);
if ($minMax[0] === '' || $minMax[1] === '') {
$this->store->setVar(SYSTEM_FORM_ELEMENT_MESSAGE, 'Missing definition of value for min or max.', STORE_SYSTEM);
throw new UserException('Missing definition of value for min or max.', ERROR_MISSING_MIN_MAX);
}
$errorText = "Value '$value' is smaller than min '$minMax[0]' or bigger than max '$minMax[1]'.";
// Date/Time: convert in object to make a comparison.
if (preg_match('date|time', $formElement['type']) === 1) {
$valueCompare = date_create($value);
$minMax[0] = date_create($minMax[0]);
$minMax[1] = date_create($minMax[1]);
}
if ($minMax[0] <= $valueCompare && $valueCompare <= $minMax[1])
return $value;
$this->store->setVar(SYSTEM_FORM_ELEMENT_MESSAGE, $errorText, STORE_SYSTEM);
throw new UserException($errorText, ERROR_MIN_MAX_VIOLATION);
break;
case 'pattern':
$pattern = $formElement['checkPattern'];
break;
case 'number':
case 'email':
$arr = OnArray::inputCheckPatternArray();
$htmlPatternAttribute = $arr[$formElement['checkType']];
// remove 'pattern="' and closing ".
$pattern = substr($htmlPatternAttribute, 9, strlen($htmlPatternAttribute) - 9 - 1);
break;
case '': // no checktype specified.
return $value;
default:
throw new CodeException("Unknown checkType: " . $formElement['checkType'], ERROR_UNKNOWN_CHECKTYPE);
}
if (preg_match($pattern, $value) === 1)
return $value;
$errorText = "Value $value violates checkrule " . $formElement['checkType'] . " with pattern '$pattern'.";
$this->store->setVar(SYSTEM_FORM_ELEMENT_MESSAGE, $errorText, STORE_SYSTEM);
throw new UserException($errorText, ERROR_PATTERN_VIOLATION);
}
} }
\ No newline at end of file
...@@ -296,7 +296,7 @@ class Store { ...@@ -296,7 +296,7 @@ class Store {
$useStores = STORE_USE_DEFAULT; $useStores = STORE_USE_DEFAULT;
} }
// no sanitizeClass specified: take last/default // no sanitizeClass specified: take predefined (if exist) or default.
if ($sanitizeClass === '' || $sanitizeClass === null) { if ($sanitizeClass === '' || $sanitizeClass === null) {
$sanitizeClass = isset(self::$sanitizeClass[$key]) ? self::$sanitizeClass[$key] : SANITIZE_DEFAULT; $sanitizeClass = isset(self::$sanitizeClass[$key]) ? self::$sanitizeClass[$key] : SANITIZE_DEFAULT;
} }
...@@ -317,7 +317,12 @@ class Store { ...@@ -317,7 +317,12 @@ class Store {
$rawVal = isset(self::$raw[$store][$key]) ? self::$raw[$store][$key] : null; $rawVal = isset(self::$raw[$store][$key]) ? self::$raw[$store][$key] : null;
if (self::$sanitizeStore[$store] && $sanitizeClass != '') { if (self::$sanitizeStore[$store] && $sanitizeClass != '') {
return \qfq\Sanitize::sanitize($rawVal, $sanitizeClass); // return \qfq\Sanitize::sanitize($rawVal, $sanitizeClass);
if ($sanitizeClass == SANITIZE_ALLOW_PATTERN || $sanitizeClass == SANITIZE_ALLOW_MIN_MAX || $sanitizeClass == SANITIZE_ALLOW_MIN_MAX_DATE) {
// We do not have any pattern or min|max values at this point. For those who be affected, they already checked earlier. So set 'no check'
$sanitizeClass = SANITIZE_ALLOW_ALL;
}
return \qfq\Sanitize::sanitize($rawVal, $sanitizeClass, '', SANATIZE_EMPTY_STRING);
} else { } else {
return $rawVal; return $rawVal;
} }
......
...@@ -71,7 +71,7 @@ CREATE TABLE IF NOT EXISTS `FormElement` ( ...@@ -71,7 +71,7 @@ CREATE TABLE IF NOT EXISTS `FormElement` (
'after_save', 'after_insert', 'after_update', 'after_delete', 'feGroup', 'after_save', 'after_insert', 'after_update', 'after_delete', 'feGroup',
'sendmail') NOT NULL DEFAULT 'text', 'sendmail') NOT NULL DEFAULT 'text',
`subrecordOption` SET('edit', 'delete', 'new') NOT NULL DEFAULT '', `subrecordOption` SET('edit', 'delete', 'new') NOT NULL DEFAULT '',
`checkType` ENUM('alnumx', 'digit', 'min|max', 'pattern', 'email', 'none') NOT NULL DEFAULT 'alnumx', `checkType` ENUM('alnumx', 'digit', 'email', 'min|max', 'min|max date', 'pattern', 'all') NOT NULL DEFAULT 'alnumx',
`checkPattern` VARCHAR(255) NOT NULL DEFAULT '', `checkPattern` VARCHAR(255) NOT NULL DEFAULT '',
`onChange` VARCHAR(255) NOT NULL DEFAULT '', `onChange` VARCHAR(255) NOT NULL DEFAULT '',
......
...@@ -94,35 +94,36 @@ class BuildFormPlainTest extends AbstractDatabaseTest { ...@@ -94,35 +94,36 @@ class BuildFormPlainTest extends AbstractDatabaseTest {
// 'tabindex' => 0 // 'tabindex' => 0
// ]; // ];
// Defaults // Defaults
$result = $build->buildInput($formElement, 'name:1', '', $json); $result = $build->buildInput($formElement, 'name:1', '', $json);
$this->assertEquals('<input name="name:1" type="input" maxlength="255" value="" >', $result); $this->assertEquals('<input name="name:1" type="input" maxlength="255" value="" >', $result);
$this->assertEquals(['form-element' => 'name:1', 'value' => '', 'disabled' => 'false', 'readonly' => 'false'], $json); $this->assertEquals(['form-element' => 'name:1', 'value' => '', 'disabled' => false, 'readonly' => false], $json);
// CheckType // CheckType
$formElement['checkType'] = 'min|max'; $formElement['checkType'] = SANITIZE_ALLOW_MIN_MAX;
$formElement['checkPattern'] = '1|10'; $formElement['checkPattern'] = '1|10';
$result = $build->buildInput($formElement, 'name:1', '', $json); $result = $build->buildInput($formElement, 'name:1', '', $json);
$this->assertEquals('<input name="name:1" type="input" maxlength="255" value="" min="1" max="10" >', $result); $this->assertEquals('<input name="name:1" type="input" maxlength="255" value="" min="1" max="10" >', $result);
$this->assertEquals(['form-element' => 'name:1', 'value' => '', 'disabled' => 'false', 'readonly' => 'false'], $json); $this->assertEquals(['form-element' => 'name:1', 'value' => '', 'disabled' => false, 'readonly' => false], $json);
$formElement['checkType'] = 'pattern'; $formElement['checkType'] = SANITIZE_ALLOW_PATTERN;
$formElement['checkPattern'] = '^[a-z]*$'; $formElement['checkPattern'] = '^[a-z]*$';
$result = $build->buildInput($formElement, 'name:1', '', $json); $result = $build->buildInput($formElement, 'name:1', '', $json);
$this->assertEquals('<input name="name:1" type="input" maxlength="255" value="" pattern="^[a-z]*$" >', $result); $this->assertEquals('<input name="name:1" type="input" maxlength="255" value="" pattern="^[a-z]*$" >', $result);
$this->assertEquals(['form-element' => 'name:1', 'value' => '', 'disabl