[Validator] Changed GroupSequenceProvider implementation

This commit is contained in:
Sebastian Hörl 2012-01-28 22:10:33 +01:00
parent 6c4455fef7
commit c3b04a3336
18 changed files with 66 additions and 107 deletions

View File

@ -19,13 +19,13 @@ namespace Symfony\Component\Validator\Constraints;
class GroupSequenceProvider class GroupSequenceProvider
{ {
/** /**
* The name of the provider class * True if the group sequence provider should be used
* @var string * @var boolean
*/ */
public $class; public $active;
public function __construct(array $options) public function __construct(array $options)
{ {
$this->class = $options['value']; $this->active = (bool)$options['value'];
} }
} }

View File

@ -17,6 +17,7 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface; use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface;
use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Mapping\MemberMetadata; use Symfony\Component\Validator\Mapping\MemberMetadata;
use Symfony\Component\Validator\GroupSequenceProviderInterface;
/** /**
* Responsible for walking over and initializing validation on different * Responsible for walking over and initializing validation on different
@ -68,10 +69,11 @@ class GraphWalker
} }
if ($group === Constraint::DEFAULT_GROUP && ($metadata->hasGroupSequence() || $metadata->hasGroupSequenceProvider())) { if ($group === Constraint::DEFAULT_GROUP && ($metadata->hasGroupSequence() || $metadata->hasGroupSequenceProvider())) {
$groups = $metadata->getGroupSequence();
if ($groupSequenceProvider = $metadata->getGroupSequenceProvider()) { if ($metadata->hasGroupSequence()) {
$groups = $groupSequenceProvider->getValidationGroups($object); $groups = $metadata->getGroupSequence();
} else {
$groups = $object->getValidationGroups();
} }
foreach ($groups as $group) { foreach ($groups as $group) {

View File

@ -20,9 +20,7 @@ interface GroupSequenceProviderInterface
* Returns which validation groups should be used for a certain state * Returns which validation groups should be used for a certain state
* of the object. * of the object.
* *
* @param mixed $object The object that is validated.
*
* @return array An array of validation groups * @return array An array of validation groups
*/ */
function getValidationGroups($object); function getValidationGroups();
} }

View File

@ -14,7 +14,6 @@ namespace Symfony\Component\Validator\Mapping;
use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\ConstraintDefinitionException; use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
use Symfony\Component\Validator\Exception\GroupDefinitionException; use Symfony\Component\Validator\Exception\GroupDefinitionException;
use Symfony\Component\Validator\GroupSequenceProviderInterface;
/** /**
* Represents all the configured constraints on a given class. * Represents all the configured constraints on a given class.
@ -30,8 +29,7 @@ class ClassMetadata extends ElementMetadata
public $properties = array(); public $properties = array();
public $getters = array(); public $getters = array();
public $groupSequence = array(); public $groupSequence = array();
public $groupSequenceProviderClass; public $groupSequenceProvider = false;
public $groupSequenceProvider;
private $reflClass; private $reflClass;
/** /**
@ -60,7 +58,7 @@ class ClassMetadata extends ElementMetadata
return array_merge(parent::__sleep(), array( return array_merge(parent::__sleep(), array(
'getters', 'getters',
'groupSequence', 'groupSequence',
'groupSequenceProviderClass', 'groupSequenceProvider',
'members', 'members',
'name', 'name',
'properties', 'properties',
@ -251,6 +249,10 @@ class ClassMetadata extends ElementMetadata
*/ */
public function setGroupSequence(array $groups) public function setGroupSequence(array $groups)
{ {
if ($this->hasGroupSequenceProvider()) {
throw new GroupDefinitionException('Defining a static group sequence is not allowed with a group sequence provider');
}
if (in_array(Constraint::DEFAULT_GROUP, $groups, true)) { if (in_array(Constraint::DEFAULT_GROUP, $groups, true)) {
throw new GroupDefinitionException(sprintf('The group "%s" is not allowed in group sequences', Constraint::DEFAULT_GROUP)); throw new GroupDefinitionException(sprintf('The group "%s" is not allowed in group sequences', Constraint::DEFAULT_GROUP));
} }
@ -299,64 +301,30 @@ class ClassMetadata extends ElementMetadata
} }
/** /**
* Sets the class name of the group sequence provider. * Sets whether a group sequence provider should be used
* *
* @param string $class Sequence provider class name * @param boolean $active
*/ */
public function setGroupSequenceProviderClass($class) public function setGroupSequenceProvider($active)
{ {
$this->groupSequenceProviderClass = $class; if ($this->hasGroupSequenceProvider()) {
$this->groupSequenceProvider = null; throw new GroupDefinitionException('Defining a group sequence provider is not allowed with a static group sequence');
}
if (!$this->getReflectionClass()->implementsInterface('Symfony\Component\Validator\GroupSequenceProviderInterface')) {
throw new GroupDefinitionException(sprintf('Class "%s" must implement GroupSequenceProviderInterface', $this->name));
}
$this->groupSequenceProvider = $active;
} }
/** /**
* Returns the name of the group sequence provider class. * Returns whether the class has a group sequence provider.
*
* @return string Class name
*/
public function getGroupSequenceProviderClass()
{
return $this->groupSequenceProviderClass;
}
/**
* Returns whether a group sequence provider is set.
* *
* @return boolean * @return boolean
*/ */
public function hasGroupSequenceProvider() public function hasGroupSequenceProvider()
{ {
return $this->groupSequenceProviderClass || $this->groupSequenceProvider;
}
/**
* Returns the group sequence provider if specified.
*
* @return GroupSequenceProviderInterface The provider or null
*/
public function getGroupSequenceProvider()
{
if (!$this->groupSequenceProvider && $this->groupSequenceProviderClass) {
$reflClass = new \ReflectionClass($this->groupSequenceProviderClass);
$interface = 'Symfony\Component\Validator\GroupSequenceProviderInterface';
if (!$reflClass->implementsInterface($interface)) {
throw new \InvalidArgumentException(sprintf('The class "%s" must implement interface "%s".', $this->groupSequenceProviderClass, $interface));
}
$this->groupSequenceProvider = $reflClass->newInstance();
}
return $this->groupSequenceProvider; return $this->groupSequenceProvider;
} }
/**
* Sets the group sequence provider.
*
* @param GroupSequenceProviderInterface $provider Group sequence provider
*/
public function setGroupSequenceProvider(GroupSequenceProviderInterface $provider)
{
$this->groupSequenceProvider = $provider;
}
} }

View File

@ -58,6 +58,9 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
// Include constraints from all implemented interfaces // Include constraints from all implemented interfaces
foreach ($metadata->getReflectionClass()->getInterfaces() as $interface) { foreach ($metadata->getReflectionClass()->getInterfaces() as $interface) {
if ('Symfony\Component\Validator\GroupSequenceProviderInterface' === $interface->getName()) {
continue;
}
$metadata->mergeConstraints($this->getClassMetadata($interface->getName())); $metadata->mergeConstraints($this->getClassMetadata($interface->getName()));
} }

View File

@ -40,7 +40,7 @@ class AnnotationLoader implements LoaderInterface
if ($constraint instanceof GroupSequence) { if ($constraint instanceof GroupSequence) {
$metadata->setGroupSequence($constraint->groups); $metadata->setGroupSequence($constraint->groups);
} elseif ($constraint instanceof GroupSequenceProvider) { } elseif ($constraint instanceof GroupSequenceProvider) {
$metadata->setGroupSequenceProviderClass($constraint->class); $metadata->setGroupSequenceProvider($constraint->active);
} elseif ($constraint instanceof Constraint) { } elseif ($constraint instanceof Constraint) {
$metadata->addConstraint($constraint); $metadata->addConstraint($constraint);
} }

View File

@ -44,7 +44,7 @@ class XmlFileLoader extends FileLoader
$xml = $this->classes[$metadata->getClassName()]; $xml = $this->classes[$metadata->getClassName()];
foreach ($xml->{'group-sequence-provider'} as $provider) { foreach ($xml->{'group-sequence-provider'} as $provider) {
$metadata->setGroupSequenceProviderClass($provider['class']); $metadata->setGroupSequenceProvider((bool)$provider['active']);
} }
foreach ($this->parseConstraints($xml->constraint) as $constraint) { foreach ($this->parseConstraints($xml->constraint) as $constraint) {

View File

@ -55,7 +55,7 @@ class YamlFileLoader extends FileLoader
$yaml = $this->classes[$metadata->getClassName()]; $yaml = $this->classes[$metadata->getClassName()];
if (isset($yaml['group_sequence_provider'])) { if (isset($yaml['group_sequence_provider'])) {
$metadata->setGroupSequenceProviderClass($yaml['group_sequence_provider']); $metadata->setGroupSequenceProvider((bool)$yaml['group_sequence_provider']);
} }
if (isset($yaml['constraints'])) { if (isset($yaml['constraints'])) {

View File

@ -66,7 +66,7 @@
Defines the name of the group sequence provider for a class. Defines the name of the group sequence provider for a class.
]]></xsd:documentation> ]]></xsd:documentation>
</xsd:annotation> </xsd:annotation>
<xsd:attribute name="class" type="xsd:string" use="required" /> <xsd:attribute name="active" type="xsd:boolean" use="required" />
</xsd:complexType> </xsd:complexType>
<xsd:complexType name="property"> <xsd:complexType name="property">

View File

@ -6,13 +6,14 @@ require_once __DIR__.'/EntityParent.php';
require_once __DIR__.'/EntityInterface.php'; require_once __DIR__.'/EntityInterface.php';
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\GroupSequenceProviderInterface;
/** /**
* @Symfony\Tests\Component\Validator\Fixtures\ConstraintA * @Symfony\Tests\Component\Validator\Fixtures\ConstraintA
* @Assert\GroupSequence({"Foo", "Entity"}) * @Assert\GroupSequence({"Foo", "Entity"})
* @Assert\GroupSequenceProvider("Symfony\Tests\Component\Validator\Fixtures\GroupSequenceProvider") * @Assert\GroupSequenceProvider("Symfony\Tests\Component\Validator\Fixtures\GroupSequenceProvider")
*/ */
class Entity extends EntityParent implements EntityInterface class Entity extends EntityParent implements EntityInterface, GroupSequenceProviderInterface
{ {
/** /**
* @Assert\NotNull * @Assert\NotNull
@ -29,6 +30,8 @@ class Entity extends EntityParent implements EntityInterface
protected $lastName; protected $lastName;
public $reference; public $reference;
protected $groups = array();
private $internal; private $internal;
public function __construct($internal = null) public function __construct($internal = null)
@ -48,4 +51,14 @@ class Entity extends EntityParent implements EntityInterface
{ {
return $this->lastName; return $this->lastName;
} }
public function setGroups($groups)
{
$this->groups = $groups;
}
public function getValidationGroups()
{
return $this->groups;
}
} }

View File

@ -1,20 +0,0 @@
<?php
namespace Symfony\Tests\Component\Validator\Fixtures;
use Symfony\Component\Validator\GroupSequenceProviderInterface;
class GroupSequenceProvider implements GroupSequenceProviderInterface
{
protected $groups = array();
public function setGroups($groups)
{
$this->groups = $groups;
}
public function getValidationGroups($object)
{
return $this->groups;
}
}

View File

@ -14,6 +14,7 @@ namespace Symfony\Tests\Component\Validator\Mapping;
use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\Constraints\Valid;
use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Exception\GroupDefinitionException;
use Symfony\Tests\Component\Validator\Fixtures\Entity; use Symfony\Tests\Component\Validator\Fixtures\Entity;
use Symfony\Tests\Component\Validator\Fixtures\ConstraintA; use Symfony\Tests\Component\Validator\Fixtures\ConstraintA;
use Symfony\Tests\Component\Validator\Fixtures\ConstraintB; use Symfony\Tests\Component\Validator\Fixtures\ConstraintB;
@ -24,7 +25,6 @@ require_once __DIR__.'/../Fixtures/Entity.php';
require_once __DIR__.'/../Fixtures/ConstraintA.php'; require_once __DIR__.'/../Fixtures/ConstraintA.php';
require_once __DIR__.'/../Fixtures/ConstraintB.php'; require_once __DIR__.'/../Fixtures/ConstraintB.php';
require_once __DIR__.'/../Fixtures/PropertyConstraint.php'; require_once __DIR__.'/../Fixtures/PropertyConstraint.php';
require_once __DIR__.'/../Fixtures/GroupSequenceProvider.php';
class ClassMetadataTest extends \PHPUnit_Framework_TestCase class ClassMetadataTest extends \PHPUnit_Framework_TestCase
{ {
@ -194,16 +194,14 @@ class ClassMetadataTest extends \PHPUnit_Framework_TestCase
public function testGroupSequenceProvider() public function testGroupSequenceProvider()
{ {
$this->assertNull($this->metadata->getGroupSequenceProvider()); $metadata = new ClassMetadata('stdClass');
$this->metadata->setGroupSequenceProviderClass('stdClass');
try { try {
$this->metadata->getGroupSequenceProvider(); $metadata->setGroupSequenceProvider(true);
$this->fail(); $this->fail();
} catch(\InvalidArgumentException $e) {} } catch(GroupDefinitionException $e) {}
$this->metadata->setGroupSequenceProviderClass('Symfony\Tests\Component\Validator\Fixtures\GroupSequenceProvider'); $this->metadata->setGroupSequenceProvider(true);
$this->assertTrue($this->metadata->getGroupSequenceProvider() instanceof GroupSequenceProvider); $this->assertTrue($this->metadata->hasGroupSequenceProvider());
} }
} }

View File

@ -73,7 +73,7 @@ class AnnotationLoaderTest extends \PHPUnit_Framework_TestCase
'choices' => array('A', 'B'), 'choices' => array('A', 'B'),
))); )));
$expected->addGetterConstraint('lastName', new NotNull()); $expected->addGetterConstraint('lastName', new NotNull());
$expected->setGroupSequenceProviderClass('Symfony\Tests\Component\Validator\Fixtures\GroupSequenceProvider'); $expected->setGroupSequenceProvider(true);
// load reflection class so that the comparison passes // load reflection class so that the comparison passes
$expected->getReflectionClass(); $expected->getReflectionClass();
@ -138,7 +138,7 @@ class AnnotationLoaderTest extends \PHPUnit_Framework_TestCase
'choices' => array('A', 'B'), 'choices' => array('A', 'B'),
))); )));
$expected->addGetterConstraint('lastName', new NotNull()); $expected->addGetterConstraint('lastName', new NotNull());
$expected->setGroupSequenceProviderClass('Symfony\Tests\Component\Validator\Fixtures\GroupSequenceProvider'); $expected->setGroupSequenceProvider(true);
// load reflection class so that the comparison passes // load reflection class so that the comparison passes
$expected->getReflectionClass(); $expected->getReflectionClass();

View File

@ -67,7 +67,7 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
'choices' => array('A', 'B'), 'choices' => array('A', 'B'),
))); )));
$expected->addGetterConstraint('lastName', new NotNull()); $expected->addGetterConstraint('lastName', new NotNull());
$expected->setGroupSequenceProviderClass('Symfony\Tests\Component\Validator\Fixtures\GroupSequenceProvider'); $expected->setGroupSequenceProvider(true);
$this->assertEquals($expected, $metadata); $this->assertEquals($expected, $metadata);
} }

View File

@ -85,7 +85,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
'choices' => array('A', 'B'), 'choices' => array('A', 'B'),
))); )));
$expected->addGetterConstraint('lastName', new NotNull()); $expected->addGetterConstraint('lastName', new NotNull());
$expected->setGroupSequenceProviderClass('Symfony\Tests\Component\Validator\Fixtures\GroupSequenceProvider'); $expected->setGroupSequenceProvider(true);
$this->assertEquals($expected, $metadata); $this->assertEquals($expected, $metadata);
} }

View File

@ -9,7 +9,7 @@
<class name="Symfony\Tests\Component\Validator\Fixtures\Entity"> <class name="Symfony\Tests\Component\Validator\Fixtures\Entity">
<!-- GROUP SEQUENCE PROVIDER --> <!-- GROUP SEQUENCE PROVIDER -->
<group-sequence-provider class="Symfony\Tests\Component\Validator\Fixtures\GroupSequenceProvider" /> <group-sequence-provider active="true" />
<!-- CLASS CONSTRAINTS --> <!-- CLASS CONSTRAINTS -->

View File

@ -2,7 +2,7 @@ namespaces:
custom: Symfony\Tests\Component\Validator\Fixtures\ custom: Symfony\Tests\Component\Validator\Fixtures\
Symfony\Tests\Component\Validator\Fixtures\Entity: Symfony\Tests\Component\Validator\Fixtures\Entity:
group_sequence_provider: Symfony\Tests\Component\Validator\Fixtures\GroupSequenceProvider group_sequence_provider: true
constraints: constraints:
# Custom constraint # Custom constraint
- Symfony\Tests\Component\Validator\Fixtures\ConstraintA: ~ - Symfony\Tests\Component\Validator\Fixtures\ConstraintA: ~

View File

@ -19,7 +19,6 @@ require_once __DIR__.'/Fixtures/FakeClassMetadataFactory.php';
use Symfony\Tests\Component\Validator\Fixtures\Entity; use Symfony\Tests\Component\Validator\Fixtures\Entity;
use Symfony\Tests\Component\Validator\Fixtures\FakeClassMetadataFactory; use Symfony\Tests\Component\Validator\Fixtures\FakeClassMetadataFactory;
use Symfony\Tests\Component\Validator\Fixtures\FailingConstraint; use Symfony\Tests\Component\Validator\Fixtures\FailingConstraint;
use Symfony\Tests\Component\Validator\Fixtures\GroupSequenceProvider;
use Symfony\Component\Validator\Validator; use Symfony\Component\Validator\Validator;
use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList; use Symfony\Component\Validator\ConstraintViolationList;
@ -125,8 +124,6 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
public function testValidate_groupSequenceProvider() public function testValidate_groupSequenceProvider()
{ {
$groupSequenceProvider = new GroupSequenceProvider;
$entity = new Entity(); $entity = new Entity();
$metadata = new ClassMetadata(get_class($entity)); $metadata = new ClassMetadata(get_class($entity));
$metadata->addPropertyConstraint('firstName', new FailingConstraint(array( $metadata->addPropertyConstraint('firstName', new FailingConstraint(array(
@ -135,7 +132,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
$metadata->addPropertyConstraint('lastName', new FailingConstraint(array( $metadata->addPropertyConstraint('lastName', new FailingConstraint(array(
'groups' => 'Second', 'groups' => 'Second',
))); )));
$metadata->setGroupSequenceProvider($groupSequenceProvider); $metadata->setGroupSequenceProvider(true);
$this->factory->addClassMetadata($metadata); $this->factory->addClassMetadata($metadata);
$violations = new ConstraintViolationList(); $violations = new ConstraintViolationList();
@ -147,7 +144,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
'' ''
)); ));
$groupSequenceProvider->setGroups(array('First')); $entity->setGroups(array('First'));
$result = $this->validator->validate($entity); $result = $this->validator->validate($entity);
$this->assertEquals($violations, $result); $this->assertEquals($violations, $result);
@ -160,11 +157,11 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
'' ''
)); ));
$groupSequenceProvider->setGroups(array('Second')); $entity->setGroups(array('Second'));
$result = $this->validator->validate($entity); $result = $this->validator->validate($entity);
$this->assertEquals($violations, $result); $this->assertEquals($violations, $result);
$groupSequenceProvider->setGroups(array()); $entity->setGroups(array());
$result = $this->validator->validate($entity); $result = $this->validator->validate($entity);
$this->assertEquals(new ConstraintViolationList(), $result); $this->assertEquals(new ConstraintViolationList(), $result);
} }