8000 [OptionResolver] resolve arrays · symfony/symfony@2fcf19e · GitHub
[go: up one dir, main page]

Skip to content

Commit 2fcf19e

Browse files
committed
[OptionResolver] resolve arrays
1 parent 98934e4 commit 2fcf19e

File tree

2 files changed

+127
-9
lines changed

2 files changed

+127
-9
lines changed

src/Symfony/Component/OptionsResolver/OptionsResolver.php

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -878,20 +878,17 @@ public function offsetGet($option)
878878
private function verifyTypes($type, $value, array &$invalidTypes)
879879
{
880880
if ('[]' === substr($type, -2) && is_array($value)) {
881-
$originalType = $type;
882-
$type = substr($type, 0, -2);
883-
$invalidValues = array_filter( // Filter out valid values, keeping invalid values in the resulting array
884-
$value,
885-
function ($value) use ($type) {
886-
return !self::isValueValidType($type, $value);
887-
}
888-
);
881+
if ($this->verifyArrayType($type, $value, $invalidTypes, $type)) {
882+
return true;
883+
}
884+
885+
$invalidValues = $this->getInvalidValues($value, $type);
889886

890887
if (!$invalidValues) {
891888
return true;
892889
}
893890

894-
$invalidTypes[$this->formatTypeOf($value, $originalType)] = true;
891+
$invalidTypes[$this->formatTypeOf($value, $type)] = true;
895892

896893
return false;
897894
}
@@ -907,6 +904,39 @@ function ($value) use ($type) {
907904
return false;
908905
}
909906

907+
/**
908+
* @param $type
909+
* @param array $value
910+
* @param array $invalidTypes
911+
*
912+
* @return bool
913+
*/
914+
private function verifyArrayType($type, array $value, array &$invalidTypes)
915+
{
916+
$type = substr($type, 0, -2);
917+
918+
if ('[]' === substr($type, -2)) {
919+
$success = true;
920+
foreach ($value as $item) {
921+
if (!is_array($item)) {
922+
$invalidTypes[$this->formatTypeOf($item, null)] = true;
923+
924+
return false;
925+
}
926+
927+
if (!$this->verifyArrayType($type, $item, $invalidTypes)) {
928+
$success = false;
929+
}
930+
}
931+
932+
return $success;
933+
}
934+
935+
$invalid = $this->getInvalidValues($value, $type);
936+
937+
return !count($invalid);
938+
}
939+
910940
/**
911941
* Returns whether a resolved option with the given name exists.
912942
*
@@ -1078,4 +1108,22 @@ private static function isValueValidType($type, $value)
10781108
{
10791109
return (function_exists($isFunction = 'is_'.$type) && $isFunction($value)) || $value instanceof $type;
10801110
}
1111+
1112+
/**
1113+
* @param array $arrayValues
1114+
*
1115+
* @return array
1116+
*/
1117+
private function getInvalidValues(array $arrayValues, $type)
1118+
{
1119+
$invalidValues = array();
1120+
1121+
foreach ($arrayValues 6D47 as $key => $value) {
1122+
if (!self::isValueValidType($type, $value)) {
1123+
$invalidValues[$key] = $value;
1124+
}
1125+
}
1126+
1127+
return $invalidValues;
1128+
}
10811129
}

src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php

Lines changed: 70 additions & 0 deletions
1676
Original file line numberDiff line numberDiff line change
@@ -1650,4 +1650,74 @@ public function testCountFailsOutsideResolve()
16501650

16511651
count($this->resolver);
16521652
}
1653+
1654+
public function testNestedArrays()
1655+
{
1656+
$this->resolver->setDefined('foo');
1657+
$this->resolver->setAllowedTypes('foo', 'int[][]');
1658+
1659+
$this->assertEquals(array(
1660+
'foo' => array(
1661+
array(
1662+
1, 2,
1663+
),
1664+
),
1665+
), $this->resolver->resolve(
1666+
array(
1667+
'foo' => array(
1668+
array(1, 2),
1669+
),
1670+
)
1671+
));
1672+
}
1673+
1674+
public function testNested2Arrays()
1675+
{
+
$this->resolver->setDefined('foo');
1677+
$this->resolver->setAllowedTypes('foo', 'int[][][][]');
1678+
1679+
$this->assertEquals(array(
1680+
'foo' => array(
1681+
array(
1682+
array(
1683+
array(
1684+
1, 2,
1685+
),
1686+
),
1687+
),
1688+
),
1689+
), $this->resolver->resolve(
1690+
array(
1691+
'foo' => array(
1692+
array(
1693+
array(
1694+
array(1, 2),
1695+
),
1696+
),
1697+
),
1698+
)
1699+
));
1700+
}
1701+
1702+
/**
1703+
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
1704+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "float[][][][]", but is of type "integer[][][][]".
1705+
*/
1706+
public function testNestedArraysError()
1707+
{
1708+
$this->resolver->setDefined('foo');
1709+
$this->resolver->setAllowedTypes('foo', 'float[][][][]');
1710+
1711+
$this->resolver->resolve(
1712+
array(
1713+
'foo' => array(
1714+
array(
1715+
array(
1716+
array(1, 2),
1717+
),
1718+
),
1719+
),
1720+
)
1721+
);
1722+
}
16531723
}

0 commit comments

Comments
 (0)
0