add groups support to the Valid constraint

This commit is contained in:
Christian Flothmann 2016-12-27 11:46:45 +01:00
parent ddc4b20934
commit 0ca27ccfde
6 changed files with 100 additions and 14 deletions

View File

@ -4,6 +4,7 @@ CHANGELOG
3.4.0
-----
* added support for validation groups to the `Valid` constraint
* not setting the `strict` option of the `Choice` constraint to `true` is
deprecated and will throw an exception in Symfony 4.0
* setting the `checkDNS` option of the `Url` constraint to `true` is deprecated in favor of constant values and will throw an exception in Symfony 4.0

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
/**
* @Annotation
@ -24,15 +23,23 @@ class Valid extends Constraint
{
public $traverse = true;
public function __construct($options = null)
public function __get($option)
{
if (is_array($options) && array_key_exists('groups', $options)) {
throw new ConstraintDefinitionException(sprintf(
'The option "groups" is not supported by the constraint %s',
__CLASS__
));
if ('groups' === $option) {
// when this is reached, no groups have been configured
return null;
}
parent::__construct($options);
return parent::__get($option);
}
/**
* {@inheritdoc}
*/
public function addImplicitGroupName($group)
{
if (null !== $this->groups) {
parent::addImplicitGroupName($group);
}
}
}

View File

@ -0,0 +1,37 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
/**
* @author Christian Flothmann <christian.flothmann@sensiolabs.de>
*/
class ValidValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
if (!$constraint instanceof Valid) {
throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Valid');
}
$violations = $this->context->getValidator()->validate($value, null, array($this->context->getGroup()));
foreach ($violations as $violation) {
$this->context->buildViolation($violation->getMessage(), $violation->getParameters())
->atPath($violation->getPropertyPath())
->addViolation();
}
}
}

View File

@ -131,7 +131,7 @@ class GenericMetadata implements MetadataInterface
));
}
if ($constraint instanceof Valid) {
if ($constraint instanceof Valid && null === $constraint->groups) {
$this->cascadingStrategy = CascadingStrategy::CASCADE;
if ($constraint->traverse) {

View File

@ -19,11 +19,17 @@ use Symfony\Component\Validator\Constraints\Valid;
*/
class ValidTest extends TestCase
{
/**
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
*/
public function testRejectGroupsOption()
public function testGroupsCanBeSet()
{
new Valid(array('groups' => 'foo'));
$constraint = new Valid(array('groups' => 'foo'));
$this->assertSame(array('foo'), $constraint->groups);
}
public function testGroupsAreNullByDefault()
{
$constraint = new Valid();
$this->assertNull($constraint->groups);
}
}

View File

@ -14,6 +14,7 @@ namespace Symfony\Component\Validator\Tests\Validator;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Constraints\Collection;
use Symfony\Component\Validator\Constraints\GroupSequence;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotNull;
use Symfony\Component\Validator\Constraints\Traverse;
use Symfony\Component\Validator\Constraints\Valid;
@ -670,4 +671,38 @@ abstract class AbstractTest extends AbstractValidatorTest
$this->assertCount(1, $violations);
$this->assertSame($constraint, $violations[0]->getConstraint());
}
public function testNestedObjectIsNotValidatedIfGroupInValidConstraintIsNotValidated()
{
$entity = new Entity();
$entity->firstName = '';
$reference = new Reference();
$reference->value = '';
$entity->childA = $reference;
$this->metadata->addPropertyConstraint('firstName', new NotBlank(array('groups' => 'group1')));
$this->metadata->addPropertyConstraint('childA', new Valid(array('groups' => 'group1')));
$this->referenceMetadata->addPropertyConstraint('value', new NotBlank());
$violations = $this->validator->validate($entity, null, array());
$this->assertCount(0, $violations);
}
public function testNestedObjectIsValidatedIfGroupInValidConstraintIsValidated()
{
$entity = new Entity();
$entity->firstName = '';
$reference = new Reference();
$reference->value = '';
$entity->childA = $reference;
$this->metadata->addPropertyConstraint('firstName', new NotBlank(array('groups' => 'group1')));
$this->metadata->addPropertyConstraint('childA', new Valid(array('groups' => 'group1')));
$this->referenceMetadata->addPropertyConstraint('value', new NotBlank(array('groups' => 'group1')));
$violations = $this->validator->validate($entity, null, array('Default', 'group1'));
$this->assertCount(2, $violations);
}
}