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