[Validator] Only traverse arrays that are cascaded into
This commit is contained in:
parent
0c8e8a50b0
commit
7db9200279
@ -68,7 +68,7 @@ class Collection extends Composite
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$field instanceof Optional && !$field instanceof Required) {
|
if (!$field instanceof Optional && !$field instanceof Required) {
|
||||||
$this->fields[$fieldName] = $field = new Required($field);
|
$this->fields[$fieldName] = new Required($field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -589,6 +589,30 @@ abstract class AbstractValidatorTest extends TestCase
|
|||||||
$this->assertNull($violations[0]->getCode());
|
$this->assertNull($violations[0]->getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testOnlyCascadedArraysAreTraversed()
|
||||||
|
{
|
||||||
|
$entity = new Entity();
|
||||||
|
$entity->reference = ['key' => new Reference()];
|
||||||
|
|
||||||
|
$callback = function ($value, ExecutionContextInterface $context) {
|
||||||
|
$context->addViolation('Message %param%', ['%param%' => 'value']);
|
||||||
|
};
|
||||||
|
|
||||||
|
$this->metadata->addPropertyConstraint('reference', new Callback([
|
||||||
|
'callback' => function () {},
|
||||||
|
'groups' => 'Group',
|
||||||
|
]));
|
||||||
|
$this->referenceMetadata->addConstraint(new Callback([
|
||||||
|
'callback' => $callback,
|
||||||
|
'groups' => 'Group',
|
||||||
|
]));
|
||||||
|
|
||||||
|
$violations = $this->validate($entity, null, 'Group');
|
||||||
|
|
||||||
|
/* @var ConstraintViolationInterface[] $violations */
|
||||||
|
$this->assertCount(0, $violations);
|
||||||
|
}
|
||||||
|
|
||||||
public function testArrayTraversalCannotBeDisabled()
|
public function testArrayTraversalCannotBeDisabled()
|
||||||
{
|
{
|
||||||
$entity = new Entity();
|
$entity = new Entity();
|
||||||
|
@ -352,24 +352,18 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
|
|||||||
* Validates each object in a collection against the constraints defined
|
* Validates each object in a collection against the constraints defined
|
||||||
* for their classes.
|
* for their classes.
|
||||||
*
|
*
|
||||||
* If the parameter $recursive is set to true, nested {@link \Traversable}
|
* Nested arrays are also iterated.
|
||||||
* objects are iterated as well. Nested arrays are always iterated,
|
|
||||||
* regardless of the value of $recursive.
|
|
||||||
*
|
*
|
||||||
* @param iterable $collection The collection
|
* @param iterable $collection The collection
|
||||||
* @param string $propertyPath The current property path
|
* @param string $propertyPath The current property path
|
||||||
* @param (string|GroupSequence)[] $groups The validated groups
|
* @param (string|GroupSequence)[] $groups The validated groups
|
||||||
* @param ExecutionContextInterface $context The current execution context
|
* @param ExecutionContextInterface $context The current execution context
|
||||||
*
|
|
||||||
* @see ClassNode
|
|
||||||
* @see CollectionNode
|
|
||||||
*/
|
*/
|
||||||
private function validateEachObjectIn($collection, $propertyPath, array $groups, ExecutionContextInterface $context)
|
private function validateEachObjectIn($collection, $propertyPath, array $groups, ExecutionContextInterface $context)
|
||||||
{
|
{
|
||||||
foreach ($collection as $key => $value) {
|
foreach ($collection as $key => $value) {
|
||||||
if (\is_array($value)) {
|
if (\is_array($value)) {
|
||||||
// Arrays are always cascaded, independent of the specified
|
// Also traverse nested arrays
|
||||||
// traversal strategy
|
|
||||||
$this->validateEachObjectIn(
|
$this->validateEachObjectIn(
|
||||||
$value,
|
$value,
|
||||||
$propertyPath.'['.$key.']',
|
$propertyPath.'['.$key.']',
|
||||||
@ -599,7 +593,8 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
|
|||||||
* in the passed metadata object. Then, if the value is an instance of
|
* in the passed metadata object. Then, if the value is an instance of
|
||||||
* {@link \Traversable} and the selected traversal strategy permits it,
|
* {@link \Traversable} and the selected traversal strategy permits it,
|
||||||
* the value is traversed and each nested object validated against its own
|
* the value is traversed and each nested object validated against its own
|
||||||
* constraints. Arrays are always traversed.
|
* constraints. If the value is an array, it is traversed regardless of
|
||||||
|
* the given strategy.
|
||||||
*
|
*
|
||||||
* @param mixed $value The validated value
|
* @param mixed $value The validated value
|
||||||
* @param object|null $object The current object
|
* @param object|null $object The current object
|
||||||
@ -658,8 +653,8 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
|
|||||||
|
|
||||||
$cascadingStrategy = $metadata->getCascadingStrategy();
|
$cascadingStrategy = $metadata->getCascadingStrategy();
|
||||||
|
|
||||||
// Quit unless we have an array or a cascaded object
|
// Quit unless we cascade
|
||||||
if (!\is_array($value) && !($cascadingStrategy & CascadingStrategy::CASCADE)) {
|
if (!($cascadingStrategy & CascadingStrategy::CASCADE)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user