@@ -5,6 +5,10 @@ Validates that a particular field (or fields) in a Doctrine entity is (are)
55unique. This is commonly used, for example, to prevent a new user to register
66using an email address that already exists in the system.
77
8+ .. versionadded :: 7.1
9+
10+ Any class instance (like DTO) field (or fields) validation against entities persisted in the database was introduced in Symfony 7.1.
11+
812.. seealso ::
913
1014 If you want to validate that all the elements of the collection are unique
@@ -162,6 +166,7 @@ the current class instance. However, in some cases, such as when using Doctrine
162166inheritance mapping, you need to execute the query in a different repository.
163167Use this option to define the fully-qualified class name (FQCN) of the Doctrine
164168entity associated with the repository you want to use.
169+ Another case is when the object being validated is not an entity.
165170
166171``errorPath ``
167172~~~~~~~~~~~~~
@@ -274,6 +279,125 @@ each with a single field.
274279
275280.. include :: /reference/constraints/_groups-option.rst.inc
276281
282+ If object being validated field name(s) do not match the one(s) from the entity,
283+ use key-value mapping; Where ``key `` is the name of the field in the object being
284+ validated and ``value `` is the name of the field in the entity.
285+ Field name(s) mapping only applies when the object being validated is not an entity.
286+
287+ ``identifierFieldNames ``
288+ ~~~~~~~~~~~~~~~~~~~~
289+
290+ **type **: ``array `` | ``string `` [:ref: `default option <validation-default-option >`]
291+
292+ Use it only when the object being validated is not an entity and you need to update an
293+ entity with it.
294+ This option is the identifier field name that is the ``primary key `` or the identifier
295+ field names that are ``composite keys `` in the entity class set by the `entityClass `_
296+ option.
297+ If set, it won’t trigger a uniqueness constraint violation when the only not unique
298+ entity identifier(s) value(s) will be matching corresponding value(s) from the
299+ object being validated.
300+ If object being validated field name(s) do not match the one(s) from the entity,
301+ use key-value mapping; Where ``key `` is the name of the field in the object being
302+ validated and ``value `` is the name of the field in the entity.
303+
304+ Consider this example:
305+
306+ .. configuration-block ::
307+
308+ .. code-block :: php-attributes
309+
310+ // src/Entity/User.php
311+ namespace App\Entity;
312+
313+ use Doctrine\ORM\Mapping as ORM;
314+
315+ #[ORM\Entity]
316+ class User
317+ {
318+ #[ORM\Column(type: 'string')]
319+ public string $id;
320+
321+ #[ORM\Column(type: 'string')]
322+ public string $username;
323+ }
324+
325+ // src/Message/UpdateEmployeeProfile.php
326+ namespace App\Message;
327+
328+ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
329+
330+ #[UniqueEntity(
331+ fields: ['name' => 'username'],
332+ entityClass: 'App\Entity\User',
333+ identifierFieldNames: ['uid' => 'id'],
334+ )]
335+ class UpdateEmployeeProfile
336+ {
337+ public function __construct(public string $uid, public string $name)
338+ {
339+ }
340+ }
341+
342+ .. code-block :: yaml
343+
344+ # config/validator/validation.yaml
345+ App\Message\UpdateEmployeeProfile :
346+ constraints :
347+ - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity :
348+ fields : {name: username}
349+ entityClass : ' App\Entity\User'
350+ identifierFieldNames : {uid: id}
351+
352+ .. code-block :: xml
353+
354+ <!-- config/validator/validation.xml -->
355+ <?xml version =" 1.0" encoding =" UTF-8" ?>
356+ <constraint-mapping xmlns =" http://symfony.com/schema/dic/constraint-mapping"
357+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
358+ xsi : schemaLocation =" http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd" >
359+
360+ <class name =" App\Message\UpdateEmployeeProfile" >
361+ <constraint name =" Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity" >
362+ <option name =" fields" >
363+ <value key =" name" >username</value >
364+ </option >
365+ <option name =" entityClass" >App\Entity\User</option >
366+ <option name =" identifierFieldNames" >
367+ <value key =" uid" >id</value >
368+ </option >
369+ </constraint >
370+ </class >
371+
372+ </constraint-mapping >
373+
374+ .. code-block :: php
375+
376+ // src/Message/UpdateEmployeeProfile.php
377+ namespace App\Message;
378+
379+ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
380+ use Symfony\Component\Validator\Mapping\ClassMetadata;
381+
382+ class UpdateEmployeeProfile
383+ {
384+ public $uid;
385+ public $name;
386+
387+ public static function loadValidatorMetadata(ClassMetadata $metadata)
388+ {
389+ $metadata->addConstraint(new UniqueEntity([
390+ 'fields' => ['name' => 'username'],
391+ 'entityClass' => 'App\Entity\User',
392+ 'identifierFieldNames' => ['uid' => 'id'],
393+ ]));
394+ }
395+ }
396+
397+ .. versionadded :: 7.1
398+
399+ The option was introduced in Symfony 7.1.
400+
277401``ignoreNull ``
278402~~~~~~~~~~~~~~
279403
0 commit comments