@@ -930,6 +930,134 @@ In this example, it will first validate all constraints in the group ``User``
930930(which is the same as the ``Default `` group). Only if all constraints in
931931that group are valid, the second group, ``Strict ``, will be validated.
932932
933+ Group Sequence Providers
934+ ~~~~~~~~~~~~~~~~~~~~~~~~
935+
936+ Imagine a ``User `` entity which can be a normal user or a premium user. When
937+ it's a premium user, some extra constraints should be added to the user entity
938+ (e.g. the credit card details). To dynamically determine which groups should
939+ be activated, you can create a Group Sequence Provider. First, create the
940+ entity and a new constraint group called ``Premium ``:
941+
942+ ..configuration-block ::
943+
944+ ..code-block ::php-annotations
945+
946+ // src/Acme/DemoBundle/Entity/User.php
947+ namespace Acme\DemoBundle\Entity;
948+
949+ use Symfony\Component\Validator\Constraints as Assert;
950+
951+ class User
952+ {
953+ // ...
954+
955+ /**
956+ * @Assert\NotBlank()
957+ */
958+ private $name;
959+
960+ /**
961+ * @Assert\CardScheme(
962+ * schemes={"VISA"},
963+ * groups={"Premium"},
964+ * )
965+ */
966+ private $creditCard;
967+ }
968+
969+ ..code-block ::yaml
970+
971+ # src/Acme/DemoBundle/Resources/config/validation.yml
972+ Acme\DemoBundle\Entity\User :
973+ properties :
974+ name :
975+ -NotBlank
976+ creditCard :
977+ -CardScheme
978+ schemes :[VISA]
979+ groups :[Premium]
980+
981+ ..code-block ::xml
982+
983+ <!-- src/Acme/DemoBundle/Resources/config/validation.xml-->
984+ <class name =" Acme\DemoBundle\Entity\User" >
985+ <property name =" name" >
986+ <constraint name =" NotBlank" />
987+ </property >
988+
989+ <property name =" creditCard" >
990+ <constraint name =" CardScheme" >
991+ <option name =" schemes" >
992+ <value >VISA</value >
993+ </option >
994+ <option name =" groups" >
995+ <value >Premium</value >
996+ </option >
997+ </constraint >
998+ </property >
999+ </class >
1000+
1001+ ..code-block ::php
1002+
1003+ // src/Acme/DemoBundle/Entity/User.php
1004+ namespace Acme\DemoBundle\Entity;
1005+
1006+ use Symfony\Component\Validator\Constraints as Assert;
1007+ use Symfony\Component\Validator\Mapping\ClassMetadata;
1008+
1009+ class User
1010+ {
1011+ private $name;
1012+ private $creditCard;
1013+
1014+ // ...
1015+
1016+ public static function loadValidatorMetadata(ClassMetadata $metadata)
1017+ {
1018+ $metadata->addPropertyConstraint('name', new Assert\NotBlank());
1019+ $metadata->addPropertyConstraint('creditCard', new Assert\CardScheme(
1020+ 'schemes' => array('VISA'),
1021+ 'groups' => array('Premium'),
1022+ ));
1023+ }
1024+ }
1025+
1026+ Now, change the ``User `` class to implement
1027+ :class: `Symfony\\ Component\\ Validation\\ GroupSequenceProviderInterface ` and
1028+ add the
1029+ :method: `Symfony\\ Component\\ Validation\\ GroupSequenceProviderInterface::getGroupSequence `,
1030+ which should return an array of groups to use. Also, add the
1031+ ``@Assert\GroupSequenceProvider `` annotation to the class. If you imagine
1032+ that a method called ``isPremium `` returns true if the user is a premium member,
1033+ then your code might look like this::
1034+
1035+ // src/Acme/DemoBundle/Entity/User.php
1036+ namespace Acme\DemoBundle\Entity;
1037+
1038+ // ...
1039+ use Symfony\Component\Validation\GroupSequenceProviderInterface;
1040+
1041+ /**
1042+ * @Assert\GroupSequenceProvider
1043+ * ...
1044+ */
1045+ class User implements GroupSequenceProviderInterface
1046+ {
1047+ // ...
1048+
1049+ public function getGroupSequence()
1050+ {
1051+ $groups = array('User');
1052+
1053+ if ($this->isPremium()) {
1054+ $groups[] = 'Premium';
1055+ }
1056+
1057+ return $groups;
1058+ }
1059+ }
1060+
9331061.. _book-validation-raw-values :
9341062
9351063Validating Values and Arrays