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

Skip to content

Commit 4f822e5

Browse files
committed
symfony#30432 fix an error message
1 parent c8d6dec commit 4f822e5

File tree

2 files changed

+59
-107
lines changed

2 files changed

+59
-107
lines changed

src/Symfony/Component/OptionsResolver/OptionsResolver.php

Lines changed: 45 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ public function setDefault($option, $value)
153153
}
154154

155155
// Ignore previous lazy options if the closure has no second parameter
156-
if (!isset($this->lazy[$option]) || !isset($params[1])) {
156+
if (!isset($this->lazy[$option], $params[1])) {
157157
$this->lazy[$option] = [];
158158
}
159159

@@ -175,7 +175,7 @@ public function setDefault($option, $value)
175175
// to resolve options with lazy closures, normalizers or validation
176176
// rules, none of which can exist for undefined options
177177
// If the option was resolved before, update the resolved value
178-
if (!isset($this->defined[$option]) || \array_key_exists($option, $this->resolved)) {
178+
if (\array_key_exists($option, $this->resolved) || !isset($this->defined[$option])) {
179179
$this->resolved[$option] = $value;
180180
}
181181

@@ -570,8 +570,16 @@ public function remove($optionNames)
570570
}
571571

572572
foreach ((array) $optionNames as $option) {
573-
unset($this->defined[$option], $this->defaults[$option], $this->required[$option], $this->resolved[$option]);
574-
unset($this->lazy[$option], $this->normalizers[$option], $this->allowedTypes[$option], $this->allowedValues[$option]);
573+
unset(
574+
$this->defined[$option],
575+
$this->defaults[$option],
576+
$this->required[$option],
577+
$this->resolved[$option],
578+
$this->lazy[$option],
579+
$this->normalizers[$option],
580+
$this->allowedTypes[$option],
581+
$this->allowedValues[$option]
582+
);
575583
}
576584

577585
return $this;
@@ -746,13 +754,16 @@ public function offsetGet($option)
746754
}
747755

748756
if (!$valid) {
749-
$keys = array_keys($invalidTypes);
750-
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]));
753-
}
754-
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))));
757+
throw new InvalidOptionsException(
758+
sprintf(
759+
'The option "%s" with value %s is expected to be of type "%s", but %s of type "%s".',
760+
$option,
761+
$this->formatValue($value),
762+
implode('" or "', $this->allowedTypes[$option]),
763+
\is_array($value) && '[]' === substr($type, -2) ? 'one of the elements is' : 'is',
764+
implode('|', $invalidTypes)
765+
)
766+
);
756767
}
757768
}
758769

@@ -830,65 +841,35 @@ public function offsetGet($option)
830841
/**
831842
* @param string $type
832843
* @param mixed $value
833-
* @param array &$invalidTypes
844+
* @param array $invalidTypes
834845
*
835846
* @return bool
836847
*/
837848
private function verifyTypes($type, $value, array &$invalidTypes)
838849
{
839850
if (\is_array($value) && '[]' === substr($type, -2)) {
840-
return $this->verifyArrayType($type, $value, $invalidTypes);
841-
}
842-
843-
if (self::isValueValidType($type, $value)) {
844-
return true;
845-
}
846-
847-
if (!$invalidTypes) {
848-
$invalidTypes[$this->formatTypeOf($value, null)] = true;
849-
}
850-
851-
return false;
852-
}
853-
854-
/**
855-
* @return bool
856-
*/
857-
private function verifyArrayType($type, array $value, array &$invalidTypes, $level = 0)
858-
{
859-
$type = substr($type, 0, -2);
860-
861-
$suffix = '[]';
862-
while (\strlen($suffix) <= $level * 2) {
863-
$suffix .= '[]';
864-
}
865-
866-
if ('[]' === substr($type, -2)) {
867-
$success = true;
868-
foreach ($value as $item) {
869-
if (!\is_array($item)) {
870-
$invalidTypes[$this->formatTypeOf($item, null).$suffix] = true;
871-
872-
return false;
873-
}
874-
875-
if (!$this->verifyArrayType($type, $item, $invalidTypes, $level + 1)) {
876-
$success = false;
851+
$type = substr($type, 0, -2);
852+
$isValid = true;
853+
foreach ($value as $val) {
854+
if (!$this->verifyTypes($type, $val, $invalidTypes)) {
855+
$isValid = false;
877856
}
878857
}
879858

880-
return $success;
859+
return $isValid;
860+
}
861+
862+
if (('null' === $type && null === $value) || (\function_exists($func = 'is_'.$type) && $func($value)) || $value instanceof $type) {
863+
return true;
881864
}
882865

883-
foreach ($value as $item) {
884-
if (!self::isValueValidType($type, $item)) {
885-
$invalidTypes[$this->formatTypeOf($item, $type).$suffix] = $value;
866+
$fmtType = $this->formatTypeOf($value);
886867

887-
return false;
888-
}
868+
if (!\in_array($fmtType, $invalidTypes, true)) {
869+
$invalidTypes [] = $fmtType;
889870
}
890871

891-
return true;
872+
return false;
892873
}
893874

894875
/**
@@ -914,6 +895,9 @@ public function offsetExists($option)
914895
/**
915896
* Not supported.
916897
*
898+
* @param $option
899+
* @param $value
900+
*
917901
* @throws AccessException
918902
*/
919903
public function offsetSet($option, $value)
@@ -924,6 +908,8 @@ public function offsetSet($option, $value)
924908
/**
925909
* Not supported.
926910
*
911+
* @param $option
912+
*
927913
* @throws AccessException
928914
*/
929915
public function offsetUnset($option)
@@ -954,43 +940,13 @@ public function count()
954940
/**
955941
* Returns a string representation of the type of the value.
956942
*
957-
* This method should be used if you pass the type of a value as
958-
* message parameter to a constraint violation. Note that such
959-
* parameters should usually not be included in messages aimed at
960-
* non-technical people.
961-
*
962-
* @param mixed $value The value to return the type of
963-
* @param string $type
943+
* @param mixed $value The value to return the type of
964944
*
965945
* @return string The type of the value
966946
*/
967-
private function formatTypeOf($value, $type)
947+
private function formatTypeOf($value)
968948
{
969-
$suffix = '';
970-
971-
if ('[]' === substr($type, -2)) {
972-
$suffix = '[]';
973-
$type = substr($type, 0, -2);
974-
while ('[]' === substr($type, -2)) {
975-
$type = substr($type, 0, -2);
976-
$value = array_shift($value);
977-
if (!\is_array($value)) {
978-
break;
979-
}
980-
$suffix .= '[]';
981-
}
982-
983-
if (\is_array($value)) {
984-
$subTypes = [];
985-
foreach ($value as $val) {
986-
$subTypes[$this->formatTypeOf($val, null)] = true;
987-
}
988-
989-
return implode('|', array_keys($subTypes)).$suffix;
990-
}
991-
}
992-
993-
return (\is_object($value) ? \get_class($value) : \gettype($value)).$suffix;
949+
return \is_object($value) ? \get_class($value) : \gettype($value);
994950
}
995951

996952
/**
@@ -1057,9 +1013,4 @@ private function formatValues(array $values)
10571013

10581014
return implode(', ', $values);
10591015
}
1060-
1061-
private static function isValueValidType($type, $value)
1062-
{
1063-
return (\function_exists($isFunction = 'is_'.$type) && $isFunction($value)) || $value instanceof $type;
1064-
}
10651016
}

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

Lines changed: 14 additions & 13 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,8 @@ 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".'],
572575
];
573576
}
574577

@@ -614,11 +617,9 @@ public function testResolveSucceedsIfTypedArray()
614617
$this->resolver->setAllowedTypes('foo', ['null', 'DateTime[]']);
615618

616619
$data = [
617-
'foo' => [
618-
new \DateTime(),
619-
new \DateTime(),
620-
],
620+
'foo' => [new \DateTime(), new \DateTime()],
621621
];
622+
622623
$result = $this->resolver->resolve($data);
623624
$this->assertEquals($data, $result);
624625
}
@@ -1637,7 +1638,7 @@ public function testNested2Arrays()
16371638

16381639
/**
16391640
* @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[][][][]".
1641+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer".
16411642
*/
16421643
public function testNestedArraysException()
16431644
{
@@ -1659,7 +1660,7 @@ public function testNestedArraysException()
16591660

16601661
/**
16611662
* @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[][]".
1663+
* @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".
16631664
*/
16641665
public function testNestedArrayException1()
16651666
{
@@ -1674,7 +1675,7 @@ public function testNestedArrayException1()
16741675

16751676
/**
16761677
* @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[][]".
1678+
* @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".
16781679
*/
16791680
public function testNestedArrayException2()
16801681
{
@@ -1689,7 +1690,7 @@ public function testNestedArrayException2()
16891690

16901691
/**
16911692
* @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[][]".
1693+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string|integer".
16931694
*/
16941695
public function testNestedArrayException3()
16951696
{
@@ -1704,7 +1705,7 @@ public function testNestedArrayException3()
17041705

17051706
/**
17061707
* @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[][][]".
1708+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer".
17081709
*/
17091710
public function testNestedArrayException4()
17101711
{
@@ -1720,7 +1721,7 @@ public function testNestedArrayException4()
17201721

17211722
/**
17221723
* @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[]".
1724+
* @expectedExceptionMessage The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array".
17241725
*/
17251726
public function testNestedArrayException5()
17261727
{

0 commit comments

Comments
 (0)
0