@@ -344,6 +344,100 @@ provides a sequence of groups to be validated:
344344 }
345345 }
346346
347+ Advanced Validation Group Provider
348+ ----------------------------------
349+
350+ In the previous section, you learned how to dynamically determine the
351+ sequence of groups to apply based on the state of your entity. This
352+ approach covers most common scenarios, but for more advanced needs, you
353+ may find it to be insufficient.
354+
355+ For instance, suppose you need to provide the sequence of groups from an
356+ external configuration or service that can change its value dynamically.
357+ Managing the entity initialization and manually setting its dependencies can
358+ be cumbersome, and the implementation might not align with the entity
359+ responsibilities.
360+
361+ To address this, you can now configure the implementation of the
362+ :class: `Symfony\\ Component\\ Validator\\ GroupProviderInterface `
363+ outside of the entity, and even register the group provider as a
364+ service if necessary.
365+
366+ Here's how you can achieve this:
367+
368+ 1) **Define a Separate Group Provider Class: ** You can create a class that
369+ implements the :class: `Symfony\\ Component\\ Validator\\ GroupProviderInterface `
370+ and handles the dynamic group sequence logic.
371+ 2) **Configure the User with the Provider: ** Use the ``provider `` option within the
372+ :class: `Symfony\\ Component\\ Validator\\ Constraints\\ GroupSequenceProvider `
373+ attribute to link the entity with the provider class.
374+ 3) **Autowiring or Manual Tagging: ** If autowiring is enabled, your custom provider
375+ will be automatically linked. Otherwise, you can manually tag your service with
376+ ``validator.group_provider ``.
377+
378+ .. configuration-block ::
379+
380+ .. code-block :: php-attributes
381+
382+ // src/Entity/User.php
383+ namespace App\Entity;
384+
385+ // ...
386+ use App\Validator\UserGroupProvider;
387+
388+ #[Assert\GroupSequenceProvider(provider: UserGroupProvider::class)]
389+ class User
390+ {
391+ // ...
392+ }
393+
394+ .. code-block :: yaml
395+
396+ # config/validator/validation.yaml
397+ App\Entity\User :
398+ group_sequence_provider : App\Validator\UserGroupProvider
399+
400+ .. code-block :: xml
401+
402+ <!-- config/validator/validation.xml -->
403+ <?xml version =" 1.0" encoding =" UTF-8" ?>
404+ <constraint-mapping xmlns =" http://symfony.com/schema/dic/constraint-mapping"
405+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
406+ xsi : schemaLocation =" http://symfony.com/schema/dic/constraint-mapping
407+ https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd" >
408+
409+ <class name =" App\Entity\User" >
410+ <group-sequence-provider >
411+ <value >App\Validator\UserGroupProvider</value >
412+ </group-sequence-provider >
413+ <!-- ... -->
414+ </class >
415+ </constraint-mapping >
416+
417+ .. code-block :: php
418+
419+ // src/Entity/User.php
420+ namespace App\Entity;
421+
422+ // ...
423+ use App\Validator\UserGroupProvider;
424+ use Symfony\Component\Validator\Mapping\ClassMetadata;
425+
426+ class User
427+ {
428+ // ...
429+
430+ public static function loadValidatorMetadata(ClassMetadata $metadata): void
431+ {
432+ $metadata->setGroupProvider(UserGroupProvider::class);
433+ $metadata->setGroupSequenceProvider(true);
434+ // ...
435+ }
436+ }
437+
438+ With this approach, you can maintain a clean separation between the entity
439+ structure and the group sequence logic, allowing for more advanced use cases.
440+
347441How to Sequentially Apply Constraints on a Single Property
348442----------------------------------------------------------
349443
0 commit comments