@@ -781,6 +781,9 @@ With this configuration, there are two validation groups:
781781
782782* ``Default `` - contains the constraints not assigned to any other group;
783783
784+ * ``User `` - contains the constraints that belongs to group ``Default ``
785+ (this group is useful for:ref: `book-validation-group-sequence `);
786+
784787* ``registration `` - contains the constraints on the ``email `` and ``password ``
785788 fields only.
786789
@@ -789,13 +792,138 @@ as the second argument to the ``validate()`` method::
789792
790793 $errors = $validator->validate($author, array('registration'));
791794
795+ If no groups are specified, all constraints that belong in group ``Default ``
796+ will be applied.
797+
792798Of course, you'll usually work with validation indirectly through the form
793799library. For information on how to use validation groups inside forms, see
794800:ref: `book-forms-validation-groups `.
795801
796802..index ::
797803 single: Validation; Validating raw values
798804
805+ .. _book-validation-group-sequence :
806+
807+ Group Sequence
808+ --------------
809+
810+ In some cases, you want to validate your groups by steps. To do this, you can
811+ use the ``GroupSequence `` feature. In the case, an object defines a group sequence,
812+ and then the groups in the group sequence are validated in order.
813+
814+ ..tip ::
815+
816+ Group sequences cannot contain the group ``Default ``, as this would create
817+ a loop. Instead, use the group ``{ClassName} `` (e.g. ``User ``) instead.
818+
819+ For example, suppose you have a ``User `` class and want to validate that the
820+ username and the password are different only if all other validation passes
821+ (in order to avoid multiple error messages).
822+
823+ ..configuration-block ::
824+
825+ ..code-block ::yaml
826+
827+ # src/Acme/BlogBundle/Resources/config/validation.yml
828+ Acme\BlogBundle\Entity\User :
829+ group_sequence :
830+ -User
831+ -Strict
832+ getters :
833+ passwordLegal :
834+ -" True " :
835+ message :" The password cannot match your username"
836+ groups :[Strict]
837+ properties :
838+ username :
839+ -NotBlank :~
840+ password :
841+ -NotBlank :~
842+
843+ ..code-block ::php-annotations
844+
845+ // src/Acme/BlogBundle/Entity/User.php
846+ namespace Acme\BlogBundle\Entity;
847+
848+ use Symfony\Component\Security\Core\User\UserInterface;
849+ use Symfony\Component\Validator\Constraints as Assert;
850+
851+ /**
852+ * @Assert\GroupSequence({"Strict", "User"})
853+ */
854+ class User implements UserInterface
855+ {
856+ /**
857+ * @Assert\NotBlank
858+ */
859+ private $username;
860+
861+ /**
862+ * @Assert\NotBlank
863+ */
864+ private $password;
865+
866+ /**
867+ * @Assert\True(message="The password cannot match your username", groups={"Strict"})
868+ */
869+ public function isPasswordLegal()
870+ {
871+ return ($this->username !== $this->password);
872+ }
873+ }
874+
875+ ..code-block ::xml
876+
877+ <!-- src/Acme/BlogBundle/Resources/config/validation.xml-->
878+ <class name =" Acme\BlogBundle\Entity\User" >
879+ <property name =" username" >
880+ <constraint name =" NotBlank" />
881+ </property >
882+ <property name =" password" >
883+ <constraint name =" NotBlank" />
884+ </property >
885+ <getter property =" passwordLegal" >
886+ <constraint name =" True" >
887+ <option name =" message" >The password cannot match your username</option >
888+ <option name =" groups" >
889+ <value >Strict</value >
890+ </option >
891+ </constraint >
892+ </getter >
893+ <group-sequence >
894+ <value >User</value >
895+ <value >Strict</value >
896+ </group-sequence >
897+ </class >
898+
899+ ..code-block ::php
900+
901+ // src/Acme/BlogBundle/Entity/User.php
902+ namespace Acme\BlogBundle\Entity;
903+
904+ use Symfony\Component\Validator\Mapping\ClassMetadata;
905+ use Symfony\Component\Validator\Constraints as Assert;
906+
907+ class User
908+ {
909+ public static function loadValidatorMetadata(ClassMetadata $metadata)
910+ {
911+ $metadata->addPropertyConstraint('username', new Assert\NotBlank());
912+ $metadata->addPropertyConstraint('password', new Assert\NotBlank());
913+
914+ $metadata->addGetterConstraint('passwordLegal', new Assert\True(array(
915+ 'message' => 'The password cannot match your first name',
916+ 'groups' => array('Strict'),
917+ )));
918+
919+ $metadata->setGroupSequence(array('User', 'Strict'));
920+ }
921+ }
922+
923+ In this example, it will first validate all constraints in the group ``User ``
924+ (which is the same as the ``Default `` group). Only if all constraints in
925+ that group are valid, the second group, ``Strict ``, will be validated.
926+
799927.. _book-validation-raw-values :
800928
801929Validating Values and Arrays