-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[OptionsResolver] support array of instance validation #17032
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d4de104
82f825c
c42c1f4
3609d44
6b1c230
0194c25
ca21329
6b639cf
8ff6aac
4ab68e0
2685d2e
1fc5ddb
0368246
82d463f
5616371
7c2613e
33b1e9c
4579f17
b189757
84c8954
c79c17b
c03ccdf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,11 @@ | ||
CHANGELOG | ||
========= | ||
|
||
3.1.0 | ||
----- | ||
|
||
* Added typed array support as allowed type | ||
|
||
2.6.0 | ||
----- | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -794,19 +794,8 @@ public function offsetGet($option) | |
$valid = false; | ||
|
||
foreach ($this->allowedTypes[$option] as $type) { | ||
$type = isset(self::$typeAliases[$type]) ? self::$typeAliases[$type] : $type; | ||
|
||
if (function_exists($isFunction = 'is_'.$type)) { | ||
if ($isFunction($value)) { | ||
$valid = true; | ||
break; | ||
} | ||
|
||
continue; | ||
} | ||
|
||
if ($value instanceof $type) { | ||
$valid = true; | ||
$valid = $this->verifyAllowedType($type, $value); | ||
if ($valid) { | ||
break; | ||
} | ||
} | ||
|
@@ -818,7 +807,7 @@ public function offsetGet($option) | |
$option, | ||
$this->formatValue($value), | ||
implode('" or "', $this->allowedTypes[$option]), | ||
$this->formatTypeOf($value) | ||
$this->formatTypeOf($value, $option) | ||
)); | ||
} | ||
} | ||
|
@@ -895,6 +884,42 @@ public function offsetGet($option) | |
return $value; | ||
} | ||
|
||
/** | ||
* Verify value is of the allowed type. Recursive method to support | ||
* typed array notation like ClassName[], or scalar arrays (int[]). | ||
* | ||
* @param string $type the required allowedType string | ||
* @param mixed $value the value | ||
* | ||
* @return bool Whether the $value is of the allowed type | ||
*/ | ||
private function verifyAllowedType($type, $value) | ||
{ | ||
if (mb_substr($type, -2) === '[]') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. all the calls to mb_substr should be replaced by plain substr calls imho |
||
//allowed type is typed array | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a space after |
||
if (!is_array($value)) { | ||
return false; | ||
} | ||
$subType = mb_substr($type, 0, -2); | ||
foreach ($value as $v) { | ||
//recursive call -> check subtype | ||
if (!$this->verifyAllowedType($subType, $v)) { | ||
return false; | ||
} | ||
} | ||
//value was array, subtypes all matched -> allowed type OK | ||
return true; | ||
} | ||
|
||
$type = isset(self::$typeAliases[$type]) ? self::$typeAliases[$type] : $type; | ||
|
||
if (function_exists($isFunction = 'is_'.$type)) { | ||
return $isFunction($value); | ||
} | ||
|
||
return ($value instanceof $type); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The parenthesis can be removed. |
||
} | ||
|
||
/** | ||
* Returns whether a resolved option with the given name exists. | ||
* | ||
|
@@ -963,15 +988,68 @@ public function count() | |
* parameters should usually not be included in messages aimed at | ||
* non-technical people. | ||
* | ||
* @param mixed $value The value to return the type of | ||
* @param mixed $value The value to return the type of | ||
* @param string $option The option that holds the value | ||
* | ||
* @return string The type of the value | ||
*/ | ||
private function formatTypeOf($value) | ||
private function formatTypeOf($value, $option = null) | ||
{ | ||
if (is_array($value) && $option) { | ||
foreach ($this->allowedTypes[$option] as $type) { | ||
if (mb_substr($type, -2) === '[]') { | ||
return $this->formatComplexTypeOf($value, $type); | ||
} | ||
} | ||
} | ||
|
||
return is_object($value) ? get_class($value) : gettype($value); | ||
} | ||
|
||
/** | ||
* Returns a string representation of the complex type of the value. | ||
* | ||
* This method should be called in formatTypeOf, if there is a complex allowed type | ||
* for an array value defined to get a more explicit exception message | ||
* | ||
* @param array $value The value to return the complex type of | ||
* @param string $type the expected type | ||
* | ||
* @return string the complex type of the value | ||
*/ | ||
private function formatComplexTypeOf(array $value, $type) | ||
{ | ||
$suffix = '[]'; | ||
$type = mb_substr($type, 0, -2); | ||
while (mb_substr($type, -2) === '[]') { | ||
$value = array_shift($value); | ||
if (!is_array($value)) { | ||
//expected a nested array, but we've already hit a scalar | ||
break; | ||
} | ||
$type = mb_substr($type, 0, -2); | ||
$suffix .= '[]'; | ||
} | ||
if (is_array($value)) { | ||
$subTypes = array(); | ||
foreach ($value as $v) { | ||
$v = $this->formatTypeOf($v); | ||
if (!isset($subTypes[$v])) { | ||
$subTypes[$v] = $v;//build unique map from the off | ||
} | ||
} | ||
$vType = implode('|', $subTypes); | ||
} else { | ||
$vType = is_object($value) ? get_class($value) : gettype($value); | ||
} | ||
|
||
return sprintf( | ||
'%s%s', | ||
$vType, | ||
$suffix | ||
); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be on one line. |
||
} | ||
|
||
/** | ||
* Returns a string representation of the value. | ||
* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be changed to 3.2.0 now.