[Validator] Implemented handling of arrays and Traversables in LegacyExecutionContext::validate()
This commit is contained in:
parent
09f744b89c
commit
ee1adadbfb
|
@ -12,6 +12,8 @@
|
|||
namespace Symfony\Component\Validator\Context;
|
||||
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
use Symfony\Component\Validator\Constraints\Traverse;
|
||||
use Symfony\Component\Validator\Constraints\Valid;
|
||||
use Symfony\Component\Validator\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Validator\ExecutionContextInterface as LegacyExecutionContextInterface;
|
||||
use Symfony\Component\Validator\Group\GroupManagerInterface;
|
||||
|
@ -100,7 +102,33 @@ class LegacyExecutionContext extends ExecutionContext implements LegacyExecution
|
|||
*/
|
||||
public function validate($value, $subPath = '', $groups = null, $traverse = false, $deep = false)
|
||||
{
|
||||
// TODO handle $traverse and $deep
|
||||
if (is_array($value)) {
|
||||
$constraint = new Traverse(array(
|
||||
'traverse' => true,
|
||||
'deep' => $deep,
|
||||
));
|
||||
|
||||
return $this
|
||||
->getValidator()
|
||||
->inContext($this)
|
||||
->atPath($subPath)
|
||||
->validateValue($value, $constraint, $groups)
|
||||
;
|
||||
}
|
||||
|
||||
if ($traverse && $value instanceof \Traversable) {
|
||||
$constraints = array(
|
||||
new Valid(),
|
||||
new Traverse(array('traverse' => true, 'deep' => $deep)),
|
||||
);
|
||||
|
||||
return $this
|
||||
->getValidator()
|
||||
->inContext($this)
|
||||
->atPath($subPath)
|
||||
->validateValue($value, $constraints, $groups)
|
||||
;
|
||||
}
|
||||
|
||||
return $this
|
||||
->getValidator()
|
||||
|
|
|
@ -15,6 +15,7 @@ use Symfony\Component\Validator\Constraint;
|
|||
use Symfony\Component\Validator\Constraints\Callback;
|
||||
use Symfony\Component\Validator\Constraints\GroupSequence;
|
||||
use Symfony\Component\Validator\ConstraintViolationInterface;
|
||||
use Symfony\Component\Validator\Context\ExecutionContext;
|
||||
use Symfony\Component\Validator\ExecutionContextInterface;
|
||||
use Symfony\Component\Validator\MetadataFactoryInterface;
|
||||
use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
|
||||
|
@ -1416,6 +1417,100 @@ abstract class AbstractValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertSame('Violation in Group 2', $violations[0]->getMessage());
|
||||
}
|
||||
|
||||
public function testValidateInContext()
|
||||
{
|
||||
$test = $this;
|
||||
$entity = new Entity();
|
||||
$entity->reference = new Reference();
|
||||
|
||||
$callback1 = function ($value, ExecutionContextInterface $context) {
|
||||
$context->validate($value->reference, 'subpath');
|
||||
};
|
||||
|
||||
$callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
|
||||
$test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
|
||||
$test->assertNull($context->getPropertyName());
|
||||
$test->assertSame('subpath', $context->getPropertyPath());
|
||||
$test->assertSame('Group', $context->getGroup());
|
||||
$test->assertSame($test->referenceMetadata, $context->getMetadata());
|
||||
$test->assertSame($test->metadataFactory, $context->getMetadataFactory());
|
||||
$test->assertSame($entity, $context->getRoot());
|
||||
$test->assertSame($entity->reference, $context->getValue());
|
||||
$test->assertSame($entity->reference, $value);
|
||||
|
||||
$context->addViolation('Message %param%', array('%param%' => 'value'));
|
||||
};
|
||||
|
||||
$this->metadata->addConstraint(new Callback(array(
|
||||
'callback' => $callback1,
|
||||
'groups' => 'Group',
|
||||
)));
|
||||
$this->referenceMetadata->addConstraint(new Callback(array(
|
||||
'callback' => $callback2,
|
||||
'groups' => 'Group',
|
||||
)));
|
||||
|
||||
$violations = $this->validator->validate($entity, 'Group');
|
||||
|
||||
/** @var ConstraintViolationInterface[] $violations */
|
||||
$this->assertCount(1, $violations);
|
||||
$this->assertSame('Message value', $violations[0]->getMessage());
|
||||
$this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
|
||||
$this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
|
||||
$this->assertSame('subpath', $violations[0]->getPropertyPath());
|
||||
$this->assertSame($entity, $violations[0]->getRoot());
|
||||
$this->assertSame($entity->reference, $violations[0]->getInvalidValue());
|
||||
$this->assertNull($violations[0]->getMessagePluralization());
|
||||
$this->assertNull($violations[0]->getCode());
|
||||
}
|
||||
|
||||
public function testValidateArrayInContext()
|
||||
{
|
||||
$test = $this;
|
||||
$entity = new Entity();
|
||||
$entity->reference = new Reference();
|
||||
|
||||
$callback1 = function ($value, ExecutionContextInterface $context) {
|
||||
$context->validate(array('key' => $value->reference), 'subpath');
|
||||
};
|
||||
|
||||
$callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
|
||||
$test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
|
||||
$test->assertNull($context->getPropertyName());
|
||||
$test->assertSame('subpath[key]', $context->getPropertyPath());
|
||||
$test->assertSame('Group', $context->getGroup());
|
||||
$test->assertSame($test->referenceMetadata, $context->getMetadata());
|
||||
$test->assertSame($test->metadataFactory, $context->getMetadataFactory());
|
||||
$test->assertSame($entity, $context->getRoot());
|
||||
$test->assertSame($entity->reference, $context->getValue());
|
||||
$test->assertSame($entity->reference, $value);
|
||||
|
||||
$context->addViolation('Message %param%', array('%param%' => 'value'));
|
||||
};
|
||||
|
||||
$this->metadata->addConstraint(new Callback(array(
|
||||
'callback' => $callback1,
|
||||
'groups' => 'Group',
|
||||
)));
|
||||
$this->referenceMetadata->addConstraint(new Callback(array(
|
||||
'callback' => $callback2,
|
||||
'groups' => 'Group',
|
||||
)));
|
||||
|
||||
$violations = $this->validator->validate($entity, 'Group');
|
||||
|
||||
/** @var ConstraintViolationInterface[] $violations */
|
||||
$this->assertCount(1, $violations);
|
||||
$this->assertSame('Message value', $violations[0]->getMessage());
|
||||
$this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
|
||||
$this->assertSame(array('%param%' => 'value'), $violations[0]->getMessageParameters());
|
||||
$this->assertSame('subpath[key]', $violations[0]->getPropertyPath());
|
||||
$this->assertSame($entity, $violations[0]->getRoot());
|
||||
$this->assertSame($entity->reference, $violations[0]->getInvalidValue());
|
||||
$this->assertNull($violations[0]->getMessagePluralization());
|
||||
$this->assertNull($violations[0]->getCode());
|
||||
}
|
||||
|
||||
public function testGetMetadataFactory()
|
||||
{
|
||||
$this->assertSame($this->metadataFactory, $this->validator->getMetadataFactory());
|
||||
|
|
|
@ -12,9 +12,7 @@
|
|||
namespace Symfony\Component\Validator\Validator;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Constraints\Traverse;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
use Symfony\Component\Validator\Exception\ValidatorException;
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadataInterface;
|
||||
use Symfony\Component\Validator\Mapping\GenericMetadata;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace Symfony\Component\Validator\Validator;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Constraints\Traverse;
|
||||
use Symfony\Component\Validator\ConstraintViolationListInterface;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextManagerInterface;
|
||||
|
@ -41,6 +42,8 @@ class ContextualValidator extends AbstractValidator implements ContextualValidat
|
|||
public function atPath($subPath)
|
||||
{
|
||||
$this->defaultPropertyPath = $this->context->getPropertyPath($subPath);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,6 +65,18 @@ class ContextualValidator extends AbstractValidator implements ContextualValidat
|
|||
return $this->context->getViolations();
|
||||
}
|
||||
|
||||
public function validateCollection($collection, $groups = null, $deep = false)
|
||||
{
|
||||
$constraint = new Traverse(array(
|
||||
'traverse' => true,
|
||||
'deep' => $deep,
|
||||
));
|
||||
|
||||
$this->traverseValue($collection, $constraint, $groups);
|
||||
|
||||
return $this->context->getViolations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a property of a value against its current value.
|
||||
*
|
||||
|
|
|
@ -24,17 +24,21 @@ class LegacyValidator extends Validator implements LegacyValidatorInterface
|
|||
public function validate($value, $groups = null, $traverse = false, $deep = false)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
return $this->validateValue($value, new Traverse(array(
|
||||
$constraint = new Traverse(array(
|
||||
'traverse' => true,
|
||||
'deep' => $deep,
|
||||
)), $groups);
|
||||
));
|
||||
|
||||
return $this->validateValue($value, $constraint, $groups);
|
||||
}
|
||||
|
||||
if ($traverse && $value instanceof \Traversable) {
|
||||
return $this->validateValue($value, array(
|
||||
$constraints = array(
|
||||
new Valid(),
|
||||
new Traverse(array('traverse' => true, 'deep' => $deep)),
|
||||
), $groups);
|
||||
);
|
||||
|
||||
return $this->validateValue($value, $constraints, $groups);
|
||||
}
|
||||
|
||||
return $this->validateObject($value, $groups);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace Symfony\Component\Validator\Validator;
|
||||
|
||||
use Symfony\Component\Validator\Constraints\Traverse;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextManagerInterface;
|
||||
use Symfony\Component\Validator\NodeTraverser\NodeTraverserInterface;
|
||||
use Symfony\Component\Validator\MetadataFactoryInterface;
|
||||
|
@ -42,6 +43,20 @@ class Validator extends AbstractValidator
|
|||
return $this->contextManager->stopContext()->getViolations();
|
||||
}
|
||||
|
||||
public function validateCollection($collection, $groups = null, $deep = false)
|
||||
{
|
||||
$this->contextManager->startContext($collection);
|
||||
|
||||
$constraint = new Traverse(array(
|
||||
'traverse' => true,
|
||||
'deep' => $deep,
|
||||
));
|
||||
|
||||
$this->traverseValue($collection, $constraint, $groups);
|
||||
|
||||
return $this->contextManager->stopContext()->getViolations();
|
||||
}
|
||||
|
||||
public function validateProperty($object, $propertyName, $groups = null)
|
||||
{
|
||||
$this->contextManager->startContext($object);
|
||||
|
|
|
@ -35,7 +35,7 @@ interface ValidatorInterface
|
|||
*/
|
||||
public function validateObject($object, $groups = null);
|
||||
|
||||
// public function validateCollection($collection, $groups = null);
|
||||
public function validateCollection($collection, $groups = null, $deep = false);
|
||||
|
||||
/**
|
||||
* Validates a property of a value against its current value.
|
||||
|
|
Reference in New Issue