8000 #30432 fix an error message · symfony/symfony@fd67b95 · GitHub
[go: up one dir, main page]

Skip to content

Commit fd67b95

Browse files
committed
#30432 fix an error message
1 parent c8d6dec commit fd67b95

File tree

2 files changed

+51
-29
lines changed

2 files changed

+51
-29
lines changed

src/Symfony/Component/OptionsResolver/OptionsResolver.php

Lines changed: 35 additions & 20 deletions

Original file line numberDiff line numberDiff line change
@@ -733,11 +733,11 @@ public function offsetGet($option)
733733
}
734734

735735
// Validate the type of the resolved option
736-
if (isset($this->allowedTypes[$option])) {
737-
$valid = false;
736+
if (isset($this->allowedTypes[$option]) && $allowedTypes = $this->allowedTypes[$option]) {
737+
$valid = true;
738738
$invalidTypes = [];
739739

740-
foreach ($this->allowedTypes[$option] as $type) {
740+
foreach ($allowedTypes as $type) {
741741
$type = isset(self::$typeAliases[$type]) ? self::$typeAliases[$type] : $type;
742742

743743
if ($valid = $this->verifyTypes($type, $value, $invalidTypes)) {
@@ -746,13 +746,22 @@ public function offsetGet($option)
746746
}
747747

748748
if (!$valid) {
749-
$keys = array_keys($invalidTypes);
749+
$fmtActualValue = $this->formatValue($value);
750+
$fmtAllowedTypes = implode('" or "', $allowedTypes);
751+
$fmtProvidedTypes = implode('|', array_keys($invalidTypes));
752+
753+
$allowedContainsArrayType = \count(array_filter(
754+
$allowedTypes,
755+
function ($item) {
756+
return '[]' === substr(isset(self::$typeAliases[$item]) ? self::$typeAliases[$item] : $item, -2);
757+
}
758+
)) > 0;
750759

751-
if (1 === \count($keys) && '[]' === substr($keys[0], -2)) {
752-
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $option, $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), $keys[0]));
760+
if (is_array($value) && $allowedContainsArrayType) {
761+
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $option, $fmtActualValue, $fmtAllowedTypes, $fmtProvidedTypes));
753762
}
754763

755-
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but is of type "%s".', $option, $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), implode('|', array_keys($invalidTypes))));
764+
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but is of type "%s".', $option, $fmtActualValue, $fmtAllowedTypes, $fmtProvidedTypes));
756765
}
757766
}
758767

@@ -852,43 +861,43 @@ private function verifyTypes($type, $value, array &$invalidTypes)
852861
}
853862

854863
/**
864+
* @param $type
865+
* @param array $value
866+
* @param array $invalidTypes
867+
* @param int $level
868+
*
855869
* @return bool
856870
*/
857871
private function verifyArrayType($type, array $value, array &$invalidTypes, $level = 0)
858872
{
859873
$type = substr($type, 0, -2);
860874

861-
$suffix = '[]';
862-
while (\strlen($suffix) <= $level * 2) {
863-
$suffix .= '[]';
864-
}
865-
866875
if ('[]' === substr($type, -2)) {
867876
$success = true;
868877
foreach ($value as $item) {
869878
if (!\is_array($item)) {
870-
$invalidTypes[$this->formatTypeOf($item, null).$suffix] = true;
871-
872-
return false;
873-
}
879+
$invalidTypes[$this->formatTypeOf($item, null)] = true;
874880
875-
if (!$this->verifyArrayType($type, $item, $invalidTypes, $level + 1)) {
881+
$success = false;
882+
} elseif (!$this->verifyArrayType($type, $item, $invalidTypes, $level + 1)) {
876883
$success = false;
877884
}
878885
}
879886

880887
return $success;
881888
}
882889

890+
$valid = true;
891+
883892
foreach ($value as $item) {
884893
if (!self::isValueValidType($type, $item)) {
885-
$invalidTypes[$this->formatTypeOf($item, $type).$suffix] = $value;
894+
$invalidTypes[$this->formatTypeOf($item, $type)] = $value;
886895

887-
return false;
896+
$valid = false;
888897
}
889898
}
890899

891-
return true;
900+
return $valid;
892901
}
893902

894903
/**
@@ -1058,6 +1067,12 @@ private function formatValues(array $values)
10581067
return implode(', ', $values);
10591068
}
10601069

1070+
/**
1071+
* @param $type
1072+
* @param $value
1073+
*
1074+
* @return bool
1075+
*/
10611076
private static function isValueValidType($type, $value)
10621077
{
10631078
return (\function_exists($isFunction = 'is_'.$type) && $isFunction($value)) || $value instanceof $type;

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

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ public function testFailIfSetAllowedTypesFromLazyOption()
483483

484484
/**
485485
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
486-
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime[]".
486+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime".
487487
*/
488488
public function testResolveFailsIfInvalidTypedArray()
489489
{
@@ -507,12 +507,13 @@ public function testResolveFailsWithNonArray()
507507

508508
/**
509509
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
510-
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass[]".
510+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass|array|DateTime".
511511
*/
512512
public function testResolveFailsIfTypedArrayContainsInvalidTypes()
513513
{
514514
$this->resolver->setDefined('foo');
515515
$this->resolver->setAllowedTypes('foo', 'int[]');
516+
516517
$values = range(1, 5);
517518
$values[] = new \stdClass();
518519
$values[] = [];
@@ -524,7 +525,7 @@ public function testResolveFailsIfTypedArrayContainsInvalidTypes()
524525

525526
/**
526527
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
527-
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double[][]".
528+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double".
528529
*/
529530
public function testResolveFailsWithCorrectLevelsButWrongScalar()
530531
{
@@ -569,6 +570,11 @@ public function provideInvalidTypes()
569570
[42, 'string', 'The option "option" with value 42 is expected to be of type "string", but is of type "integer".'],
570571
[null, 'string', 'The option "option" with value null is expected to be of type "string", but is of type "NULL".'],
571572
['bar', '\stdClass', 'The option "option" with value "bar" is expected to be of type "\stdClass", but is of type "string".'],
573+
[['foo', 12], 'string[]', 'The option "option" with value array is expected to be of type "string[]", but one of the elements is of type "integer".'],
574+
[123, ['string[]', 'string'], 'The option "option" with value 123 is expected to be of type "string[]" or "string", but is of type "integer".'],
575+
[[null], ['string[]', 'string'], 'The option "option" with value array is expected to be of type "string[]" or "string", but one of the elements is of type "NULL".'],
576+
[['string', null], ['string[]', 'string'], 'The option "option" with value array is expected to be isValueValidTypeof type "string[]" or "string", but one of the elements is of type "NULL".'],
577+
[[\stdClass::class], ['string'], 'The option "option" with value array is expected to be of type "string", but is of type "array".'],
572578
];
573579
}
574580

@@ -619,6 +625,7 @@ public function testResolveSucceedsIfTypedArray()
619625
new \DateTime(),
620626
],
621627
];
628+
622629
$result = $this->resolver->resolve($data);
623630
$this->assertEquals($data, $result);
624631
}
@@ -1637,7 +1644,7 @@ public function testNested2Arrays()
16371644

16381645
/**
16391646
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
1640-
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer[][][][]".
1647+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer".
16411648
*/
16421649
public function testNestedArraysException()
16431650
{
@@ -1659,7 +1666,7 @@ public function testNestedArraysException()
16591666

16601667
/**
16611668
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
1662-
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".
1669+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean|string|array".
16631670
*/
16641671
public function testNestedArrayException1()
16651672
{
@@ -1674,7 +1681,7 @@ public function testNestedArrayException1()
16741681

16751682
/**
16761683
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
1677-
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".
1684+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean|string|array".
16781685
*/
16791686
public function testNestedArrayException2()
16801687
{
@@ -1689,7 +1696,7 @@ public function testNestedArrayException2()
16891696

16901697
/**
16911698
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
1692-
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string[][]".
1699+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string|integer".
16931700
*/
16941701
public function testNestedArrayException3()
16951702
{
@@ -1704,7 +1711,7 @@ public function testNestedArrayException3()
17041711

17051712
/**
17061713
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
1707-
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer[][][]".
1714+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer".
17081715
*/
17091716
public function testNestedArrayException4()
17101717
{
@@ -1720,7 +1727,7 @@ public function testNestedArrayException4()
17201727

17211728
/**
17221729
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
1723-
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array[]".
1730+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array".
17241731
*/
17251732
public function testNestedArrayException5()
17261733
{

0 commit comments

Comments
 (0)
0