[Validator] Made sure that context changes don't leak out of (Contextual)ValidatorInterface

This commit is contained in:
Bernhard Schussek 2014-07-17 17:54:00 +02:00
parent 2f7b702e3b
commit 91bf2774a2
5 changed files with 87 additions and 6 deletions

View File

@ -147,7 +147,7 @@ class ExecutionContext implements ExecutionContextInterface
/**
* {@inheritdoc}
*/
public function setNode($value, $object, MetadataInterface $metadata, $propertyPath)
public function setNode($value, $object, MetadataInterface $metadata = null, $propertyPath)
{
$this->value = $value;
$this->object = $object;

View File

@ -124,7 +124,7 @@ interface ExecutionContextInterface extends LegacyExecutionContextInterface
* @internal Used by the validator engine. Should not be called by user
* code.
*/
public function setNode($value, $object, MetadataInterface $metadata, $propertyPath);
public function setNode($value, $object, MetadataInterface $metadata = null, $propertyPath);
/**
* Sets the currently validated group.

View File

@ -193,13 +193,26 @@ abstract class Abstract2Dot5ApiTest extends AbstractValidatorTest
$entity = new Entity();
$entity->reference = new Reference();
$callback1 = function ($value, ExecutionContextInterface $context) {
$callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
$previousValue = $context->getValue();
$previousObject = $context->getObject();
$previousMetadata = $context->getMetadata();
$previousPath = $context->getPropertyPath();
$previousGroup = $context->getGroup();
$context
->getValidator()
->inContext($context)
->atPath('subpath')
->validate($value->reference)
;
// context changes shouldn't leak out of the validate() call
$test->assertSame($previousValue, $context->getValue());
$test->assertSame($previousObject, $context->getObject());
$test->assertSame($previousMetadata, $context->getMetadata());
$test->assertSame($previousPath, $context->getPropertyPath());
$test->assertSame($previousGroup, $context->getGroup());
};
$callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
@ -244,13 +257,26 @@ abstract class Abstract2Dot5ApiTest extends AbstractValidatorTest
$entity = new Entity();
$entity->reference = new Reference();
$callback1 = function ($value, ExecutionContextInterface $context) {
$callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
$previousValue = $context->getValue();
$previousObject = $context->getObject();
$previousMetadata = $context->getMetadata();
$previousPath = $context->getPropertyPath();
$previousGroup = $context->getGroup();
$context
->getValidator()
->inContext($context)
->atPath('subpath')
->validate(array('key' => $value->reference))
;
// context changes shouldn't leak out of the validate() call
$test->assertSame($previousValue, $context->getValue());
$test->assertSame($previousObject, $context->getObject());
$test->assertSame($previousMetadata, $context->getMetadata());
$test->assertSame($previousPath, $context->getPropertyPath());
$test->assertSame($previousGroup, $context->getGroup());
};
$callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {

View File

@ -120,8 +120,19 @@ abstract class AbstractLegacyApiTest extends AbstractValidatorTest
$entity = new Entity();
$entity->reference = new Reference();
$callback1 = function ($value, ExecutionContextInterface $context) {
$callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
$previousValue = $context->getValue();
$previousMetadata = $context->getMetadata();
$previousPath = $context->getPropertyPath();
$previousGroup = $context->getGroup();
$context->validate($value->reference, 'subpath');
// context changes shouldn't leak out of the validate() call
$test->assertSame($previousValue, $context->getValue());
$test->assertSame($previousMetadata, $context->getMetadata());
$test->assertSame($previousPath, $context->getPropertyPath());
$test->assertSame($previousGroup, $context->getGroup());
};
$callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
@ -167,8 +178,19 @@ abstract class AbstractLegacyApiTest extends AbstractValidatorTest
$entity = new Entity();
$entity->reference = new Reference();
$callback1 = function ($value, ExecutionContextInterface $context) {
$callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
$previousValue = $context->getValue();
$previousMetadata = $context->getMetadata();
$previousPath = $context->getPropertyPath();
$previousGroup = $context->getGroup();
$context->validate(array('key' => $value->reference), 'subpath');
// context changes shouldn't leak out of the validate() call
$test->assertSame($previousValue, $context->getValue());
$test->assertSame($previousMetadata, $context->getMetadata());
$test->assertSame($previousPath, $context->getPropertyPath());
$test->assertSame($previousGroup, $context->getGroup());
};
$callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {

View File

@ -96,6 +96,12 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
{
$groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups;
$previousValue = $this->context->getValue();
$previousObject = $this->context->getObject();
$previousMetadata = $this->context->getMetadata();
$previousPath = $this->context->getPropertyPath();
$previousGroup = $this->context->getGroup();
// If explicit constraints are passed, validate the value against
// those constraints
if (null !== $constraints) {
@ -120,6 +126,9 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
$this->context
);
$this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
$this->context->setGroup($previousGroup);
return $this;
}
@ -134,6 +143,9 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
$this->context
);
$this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
$this->context->setGroup($previousGroup);
return $this;
}
@ -148,6 +160,9 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
$this->context
);
$this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
$this->context->setGroup($previousGroup);
return $this;
}
@ -180,6 +195,12 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
$groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups;
$cacheKey = spl_object_hash($object);
$previousValue = $this->context->getValue();
$previousObject = $this->context->getObject();
$previousMetadata = $this->context->getMetadata();
$previousPath = $this->context->getPropertyPath();
$previousGroup = $this->context->getGroup();
foreach ($propertyMetadatas as $propertyMetadata) {
$propertyValue = $propertyMetadata->getPropertyValue($object);
@ -196,6 +217,9 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
);
}
$this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
$this->context->setGroup($previousGroup);
return $this;
}
@ -221,6 +245,12 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
$groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups;
$cacheKey = spl_object_hash($object);
$previousValue = $this->context->getValue();
$previousObject = $this->context->getObject();
$previousMetadata = $this->context->getMetadata();
$previousPath = $this->context->getPropertyPath();
$previousGroup = $this->context->getGroup();
foreach ($propertyMetadatas as $propertyMetadata) {
$this->validateGenericNode(
$value,
@ -235,6 +265,9 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
);
}
$this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
$this->context->setGroup($previousGroup);
return $this;
}