Remove some magic from TypeValidator logic and OptionsResolver type verify logic

This commit is contained in:
Alexandru Patranescu 2020-05-13 03:38:10 +03:00 committed by Nicolas Grekas
parent a73523b065
commit e8c9049a5a
4 changed files with 60 additions and 17 deletions

View File

@ -27,6 +27,26 @@ use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException;
*/
class OptionsResolver implements Options
{
private const VALIDATION_FUNCTIONS = [
'bool' => 'is_bool',
'boolean' => 'is_bool',
'int' => 'is_int',
'integer' => 'is_int',
'long' => 'is_int',
'float' => 'is_float',
'double' => 'is_float',
'real' => 'is_float',
'numeric' => 'is_numeric',
'string' => 'is_string',
'scalar' => 'is_scalar',
'array' => 'is_array',
'iterable' => 'is_iterable',
'countable' => 'is_countable',
'callable' => 'is_callable',
'object' => 'is_object',
'resource' => 'is_resource',
];
/**
* The names of all defined options.
*/
@ -110,12 +130,6 @@ class OptionsResolver implements Options
private $parentsOptions = [];
private static $typeAliases = [
'boolean' => 'bool',
'integer' => 'int',
'double' => 'float',
];
/**
* Sets the default value of a given option.
*
@ -995,8 +1009,6 @@ class OptionsResolver implements Options
$invalidTypes = [];
foreach ($this->allowedTypes[$option] as $type) {
$type = self::$typeAliases[$type] ?? $type;
if ($valid = $this->verifyTypes($type, $value, $invalidTypes)) {
break;
}
@ -1007,7 +1019,7 @@ class OptionsResolver implements Options
$fmtAllowedTypes = implode('" or "', $this->allowedTypes[$option]);
$fmtProvidedTypes = implode('|', array_keys($invalidTypes));
$allowedContainsArrayType = \count(array_filter($this->allowedTypes[$option], static function ($item) {
return '[]' === substr(self::$typeAliases[$item] ?? $item, -2);
return '[]' === substr($item, -2);
})) > 0;
if (\is_array($value) && $allowedContainsArrayType) {
@ -1135,7 +1147,7 @@ class OptionsResolver implements Options
return $valid;
}
if (('null' === $type && null === $value) || (\function_exists($func = 'is_'.$type) && $func($value)) || $value instanceof $type) {
if (('null' === $type && null === $value) || (isset(self::VALIDATION_FUNCTIONS[$type]) ? self::VALIDATION_FUNCTIONS[$type]($value) : $value instanceof $type)) {
return true;
}

View File

@ -18,6 +18,7 @@
"require": {
"php": "^7.2.5",
"symfony/deprecation-contracts": "^2.1",
"symfony/polyfill-php73": "~1.0",
"symfony/polyfill-php80": "^1.15"
},
"autoload": {

View File

@ -20,6 +20,38 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
*/
class TypeValidator extends ConstraintValidator
{
private const VALIDATION_FUNCTIONS = [
'bool' => 'is_bool',
'boolean' => 'is_bool',
'int' => 'is_int',
'integer' => 'is_int',
'long' => 'is_int',
'float' => 'is_float',
'double' => 'is_float',
'real' => 'is_float',
'numeric' => 'is_numeric',
'string' => 'is_string',
'scalar' => 'is_scalar',
'array' => 'is_array',
'iterable' => 'is_iterable',
'countable' => 'is_countable',
'callable' => 'is_callable',
'object' => 'is_object',
'resource' => 'is_resource',
'null' => 'is_null',
'alnum' => 'ctype_alnum',
'alpha' => 'ctype_alpha',
'cntrl' => 'ctype_cntrl',
'digit' => 'ctype_digit',
'graph' => 'ctype_graph',
'lower' => 'ctype_lower',
'print' => 'ctype_print',
'punct' => 'ctype_punct',
'space' => 'ctype_space',
'upper' => 'ctype_upper',
'xdigit' => 'ctype_xdigit',
];
/**
* {@inheritdoc}
*/
@ -37,14 +69,11 @@ class TypeValidator extends ConstraintValidator
foreach ($types as $type) {
$type = strtolower($type);
$type = 'boolean' === $type ? 'bool' : $type;
$isFunction = 'is_'.$type;
$ctypeFunction = 'ctype_'.$type;
if (\function_exists($isFunction) && $isFunction($value)) {
if (isset(self::VALIDATION_FUNCTIONS[$type]) && self::VALIDATION_FUNCTIONS[$type]($value)) {
return;
} elseif (\function_exists($ctypeFunction) && $ctypeFunction($value)) {
return;
} elseif ($value instanceof $type) {
}
if ($value instanceof $type) {
return;
}
}

View File

@ -19,6 +19,7 @@
"php": "^7.2.5",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "~1.0",
"symfony/polyfill-php80": "^1.15",
"symfony/translation-contracts": "^1.1|^2"
},