Browse Source

[Validator] Group sequences must now always contain the group "<ClassName>" and never the group "Default" since that group is redefined by the group sequence

Bernhard Schussek 14 years ago
parent
commit
68cebd667a

+ 16 - 0
src/Symfony/Component/Validator/Exception/GroupDefinitionException.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace Symfony\Component\Validator\Exception;
+
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+class GroupDefinitionException extends ValidatorException
+{
+}

+ 31 - 11
src/Symfony/Component/Validator/Mapping/ClassMetadata.php

@@ -14,11 +14,12 @@ namespace Symfony\Component\Validator\Mapping;
 use Symfony\Component\Validator\Constraint;
 use Symfony\Component\Validator\Constraints\Valid;
 use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+use Symfony\Component\Validator\Exception\GroupDefinitionException;
 
 class ClassMetadata extends ElementMetadata
 {
     public $name;
-    public $shortName;
+    public $defaultGroup;
     public $members = array();
     public $properties = array();
     public $getters = array();
@@ -33,7 +34,8 @@ class ClassMetadata extends ElementMetadata
     public function __construct($class)
     {
         $this->name = $class;
-        $this->shortName = substr($class, strrpos($class, '\\') + 1);
+        // class name without namespace
+        $this->defaultGroup = substr($class, strrpos($class, '\\') + 1);
     }
 
     /**
@@ -49,7 +51,7 @@ class ClassMetadata extends ElementMetadata
             'members',
             'name',
             'properties',
-            'shortName'
+            'defaultGroup'
         ));
     }
 
@@ -64,13 +66,23 @@ class ClassMetadata extends ElementMetadata
     }
 
     /**
-     * Returns the class name without namespace
+     * Returns the name of the default group for this class
      *
-     * @return string  The local class name in the namespace
+     * For each class, the group "Default" is an alias for the group
+     * "<ClassName>", where <ClassName> is the non-namespaced name of the
+     * class. All constraints implicitely or explicitely assigned to group
+     * "Default" belong to both of these groups, unless the class defines
+     * a group sequence.
+     *
+     * If a class defines a group sequence, validating the class in "Default"
+     * will validate the group sequence. The constraints assinged to "Default"
+     * can still be validated by validating the class in "<ClassName>".
+     *
+     * @return string  The name of the default group
      */
-    public function getShortClassName()
+    public function getDefaultGroup()
     {
-        return $this->shortName;
+        return $this->defaultGroup;
     }
 
     /**
@@ -82,7 +94,7 @@ class ClassMetadata extends ElementMetadata
             throw new ConstraintDefinitionException('The constraint Valid can only be put on properties or getters');
         }
 
-        $constraint->addImplicitGroupName($this->getShortClassName());
+        $constraint->addImplicitGroupName($this->getDefaultGroup());
 
         parent::addConstraint($constraint);
     }
@@ -103,7 +115,7 @@ class ClassMetadata extends ElementMetadata
             $this->addMemberMetadata($this->properties[$property]);
         }
 
-        $constraint->addImplicitGroupName($this->getShortClassName());
+        $constraint->addImplicitGroupName($this->getDefaultGroup());
 
         $this->properties[$property]->addConstraint($constraint);
 
@@ -129,7 +141,7 @@ class ClassMetadata extends ElementMetadata
             $this->addMemberMetadata($this->getters[$property]);
         }
 
-        $constraint->addImplicitGroupName($this->getShortClassName());
+        $constraint->addImplicitGroupName($this->getDefaultGroup());
 
         $this->getters[$property]->addConstraint($constraint);
 
@@ -152,7 +164,7 @@ class ClassMetadata extends ElementMetadata
                 $member = clone $member;
 
                 foreach ($member->getConstraints() as $constraint) {
-                    $constraint->addImplicitGroupName($this->getShortClassName());
+                    $constraint->addImplicitGroupName($this->getDefaultGroup());
                 }
 
                 $this->addMemberMetadata($member);
@@ -213,6 +225,14 @@ class ClassMetadata extends ElementMetadata
      */
     public function setGroupSequence(array $groups)
     {
+        if (in_array(Constraint::DEFAULT_GROUP, $groups, true)) {
+            throw new GroupDefinitionException(sprintf('The group "%s" is not allowed in group sequences', Constraint::DEFAULT_GROUP));
+        }
+
+        if (!in_array($this->getDefaultGroup(), $groups, true)) {
+            throw new GroupDefinitionException(sprintf('The group "%s" is missing in the group sequence', $this->getDefaultGroup()));
+        }
+
         $this->groupSequence = $groups;
 
         return $this;

+ 6 - 6
tests/Symfony/Tests/Component/Validator/GraphWalkerTest.php

@@ -72,9 +72,9 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase
             'groups' => 'First',
         )));
         $this->metadata->addGetterConstraint('lastName', new FailingConstraint(array(
-            'groups' => 'Second',
+            'groups' => 'Default',
         )));
-        $this->metadata->setGroupSequence(array('First', 'Second'));
+        $this->metadata->setGroupSequence(array('First', $this->metadata->getDefaultGroup()));
 
         $this->walker->walkClass($this->metadata, $entity, 'Default', '');
 
@@ -98,7 +98,7 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase
         $entity->reference = new Reference();
 
         $this->metadata->addPropertyConstraint('reference', new Valid());
-        $this->metadata->setGroupSequence(array('First'));
+        $this->metadata->setGroupSequence(array($this->metadata->getDefaultGroup()));
 
         $referenceMetadata = new ClassMetadata(get_class($entity->reference));
         $referenceMetadata->addConstraint(new FailingConstraint(array(
@@ -132,11 +132,11 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase
             'groups' => 'First',
         )));
         $this->metadata->addGetterConstraint('lastName', new FailingConstraint(array(
-            'groups' => 'Second',
+            'groups' => $this->metadata->getDefaultGroup(),
         )));
-        $this->metadata->setGroupSequence(array('First', 'Second'));
+        $this->metadata->setGroupSequence(array('First', $this->metadata->getDefaultGroup()));
 
-        $this->walker->walkClass($this->metadata, $entity, 'Second', '');
+        $this->walker->walkClass($this->metadata, $entity, $this->metadata->getDefaultGroup(), '');
 
         // Only group "Second" was validated
         $violations = new ConstraintViolationList();

+ 27 - 7
tests/Symfony/Tests/Component/Validator/Mapping/ClassMetadataTest.php

@@ -2,16 +2,17 @@
 
 namespace Symfony\Tests\Component\Validator\Mapping;
 
-require_once __DIR__.'/../Fixtures/Entity.php';
-require_once __DIR__.'/../Fixtures/ConstraintA.php';
-require_once __DIR__.'/../Fixtures/ConstraintB.php';
-
-use Symfony\Tests\Component\Validator\Fixtures\Entity;
-use Symfony\Tests\Component\Validator\Fixtures\ConstraintA;
-use Symfony\Tests\Component\Validator\Fixtures\ConstraintB;
+use Symfony\Component\Validator\Constraint;
 use Symfony\Component\Validator\Constraints\Valid;
 use Symfony\Component\Validator\Mapping\ClassMetadata;
 use Symfony\Component\Validator\Mapping\PropertyMetadata;
+use Symfony\Tests\Component\Validator\Fixtures\Entity;
+use Symfony\Tests\Component\Validator\Fixtures\ConstraintA;
+use Symfony\Tests\Component\Validator\Fixtures\ConstraintB;
+
+require_once __DIR__.'/../Fixtures/Entity.php';
+require_once __DIR__.'/../Fixtures/ConstraintA.php';
+require_once __DIR__.'/../Fixtures/ConstraintB.php';
 
 class ClassMetadataTest extends \PHPUnit_Framework_TestCase
 {
@@ -139,5 +140,24 @@ class ClassMetadataTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals($this->metadata, $metadata);
     }
+
+    public function testGroupSequencesWorkIfContainingDefaultGroup()
+    {
+        $this->metadata->setGroupSequence(array('Foo', $this->metadata->getDefaultGroup()));
+    }
+
+    public function testGroupSequencesFailIfNotContainingDefaultGroup()
+    {
+        $this->setExpectedException('Symfony\Component\Validator\Exception\GroupDefinitionException');
+
+        $this->metadata->setGroupSequence(array('Foo', 'Bar'));
+    }
+
+    public function testGroupSequencesFailIfContainingDefault()
+    {
+        $this->setExpectedException('Symfony\Component\Validator\Exception\GroupDefinitionException');
+
+        $this->metadata->setGroupSequence(array('Foo', $this->metadata->getDefaultGroup(), Constraint::DEFAULT_GROUP));
+    }
 }