mirror of
https://github.com/symfony/symfony-docs.git
synced 2026-03-24 00:32:14 +01:00
388 lines
14 KiB
ReStructuredText
388 lines
14 KiB
ReStructuredText
Collection
|
|
==========
|
|
|
|
This constraint is used when the underlying data is a collection (i.e. an
|
|
array or an object that implements ``Traversable`` and ``ArrayAccess``),
|
|
but you'd like to validate different keys of that collection in different
|
|
ways. For example, you might validate the ``email`` key using the ``Email``
|
|
constraint and the ``inventory`` key of the collection with the ``Range``
|
|
constraint.
|
|
|
|
This constraint can also make sure that certain collection keys are present
|
|
and that extra keys are not present.
|
|
|
|
.. seealso::
|
|
|
|
If you want to validate that all the elements of the collection are unique
|
|
use the :doc:`Unique constraint </reference/constraints/Unique>`.
|
|
|
|
========== ===================================================================
|
|
Applies to :ref:`property or method <validation-property-target>`
|
|
Class :class:`Symfony\\Component\\Validator\\Constraints\\Collection`
|
|
Validator :class:`Symfony\\Component\\Validator\\Constraints\\CollectionValidator`
|
|
========== ===================================================================
|
|
|
|
Basic Usage
|
|
-----------
|
|
|
|
The ``Collection`` constraint allows you to validate the different keys
|
|
of a collection individually. Take the following example::
|
|
|
|
// src/Entity/Author.php
|
|
namespace App\Entity;
|
|
|
|
class Author
|
|
{
|
|
protected array $profileData = [
|
|
'personal_email' => '...',
|
|
'short_bio' => '...',
|
|
];
|
|
|
|
public function setProfileData($key, $value): void
|
|
{
|
|
$this->profileData[$key] = $value;
|
|
}
|
|
}
|
|
|
|
To validate that the ``personal_email`` element of the ``profileData`` array
|
|
property is a valid email address and that the ``short_bio`` element is
|
|
not blank but is no longer than 100 characters in length, you would do the
|
|
following:
|
|
|
|
.. configuration-block::
|
|
|
|
.. code-block:: php-attributes
|
|
|
|
// src/Entity/Author.php
|
|
namespace App\Entity;
|
|
|
|
use Symfony\Component\Validator\Constraints as Assert;
|
|
|
|
class Author
|
|
{
|
|
#[Assert\Collection(
|
|
fields: [
|
|
'personal_email' => new Assert\Email,
|
|
'short_bio' => [
|
|
new Assert\NotBlank,
|
|
new Assert\Length(
|
|
max: 100,
|
|
maxMessage: 'Your short bio is too long!'
|
|
)
|
|
]
|
|
],
|
|
allowMissingFields: true,
|
|
)]
|
|
protected array $profileData = [
|
|
'personal_email' => '...',
|
|
'short_bio' => '...',
|
|
];
|
|
}
|
|
|
|
.. code-block:: yaml
|
|
|
|
# config/validator/validation.yaml
|
|
App\Entity\Author:
|
|
properties:
|
|
profileData:
|
|
- Collection:
|
|
fields:
|
|
personal_email:
|
|
- Email: ~
|
|
short_bio:
|
|
- NotBlank: ~
|
|
- Length:
|
|
max: 100
|
|
maxMessage: Your short bio is too long!
|
|
allowMissingFields: true
|
|
|
|
.. code-block:: xml
|
|
|
|
<!-- config/validator/validation.xml -->
|
|
<?xml version="1.0" encoding="UTF-8" ?>
|
|
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
|
|
|
|
<class name="App\Entity\Author">
|
|
<property name="profileData">
|
|
<constraint name="Collection">
|
|
<option name="fields">
|
|
<value key="personal_email">
|
|
<constraint name="Email"/>
|
|
</value>
|
|
<value key="short_bio">
|
|
<constraint name="NotBlank"/>
|
|
<constraint name="Length">
|
|
<option name="max">100</option>
|
|
<option name="maxMessage">Your short bio is too long!</option>
|
|
</constraint>
|
|
</value>
|
|
</option>
|
|
<option name="allowMissingFields">true</option>
|
|
</constraint>
|
|
</property>
|
|
</class>
|
|
</constraint-mapping>
|
|
|
|
.. code-block:: php
|
|
|
|
// src/Entity/Author.php
|
|
namespace App\Entity;
|
|
|
|
use Symfony\Component\Validator\Constraints as Assert;
|
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
|
|
|
class Author
|
|
{
|
|
// ...
|
|
|
|
public static function loadValidatorMetadata(ClassMetadata $metadata): void
|
|
{
|
|
$metadata->addPropertyConstraint('profileData', new Assert\Collection(
|
|
fields: [
|
|
'personal_email' => new Assert\Email(),
|
|
'short_bio' => [
|
|
new Assert\NotBlank(),
|
|
new Assert\Length(
|
|
max: 100,
|
|
maxMessage: 'Your short bio is too long!',
|
|
),
|
|
],
|
|
],
|
|
allowMissingFields: true,
|
|
));
|
|
}
|
|
}
|
|
|
|
Presence and Absence of Fields
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
By default, this constraint validates more than whether or not the
|
|
individual fields in the collection pass their assigned constraints. In
|
|
fact, if any keys of a collection are missing or if there are any unrecognized
|
|
keys in the collection, validation errors will be thrown.
|
|
|
|
If you would like to allow for keys to be absent from the collection or
|
|
if you would like "extra" keys to be allowed in the collection, you can
|
|
modify the `allowMissingFields`_ and `allowExtraFields`_ options respectively.
|
|
In the above example, the ``allowMissingFields`` option was set to true,
|
|
meaning that if either of the ``personal_email`` or ``short_bio`` elements
|
|
were missing from the ``$personalData`` property, no validation error would
|
|
occur.
|
|
|
|
Required and Optional Field Constraints
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Constraints for fields within a collection can be wrapped in the ``Required``
|
|
or ``Optional`` constraint to control whether they should always be applied
|
|
(``Required``) or only applied when the field is present (``Optional``).
|
|
|
|
For instance, if you want to require that the ``personal_email`` field of
|
|
the ``profileData`` array is not blank and is a valid email but the
|
|
``alternate_email`` field is optional but must be a valid email if supplied,
|
|
you can do the following:
|
|
|
|
.. configuration-block::
|
|
|
|
.. code-block:: php-attributes
|
|
|
|
// src/Entity/Author.php
|
|
namespace App\Entity;
|
|
|
|
use Symfony\Component\Validator\Constraints as Assert;
|
|
|
|
class Author
|
|
{
|
|
#[Assert\Collection(
|
|
fields: [
|
|
'personal_email' => new Assert\Required([
|
|
new Assert\NotBlank,
|
|
new Assert\Email,
|
|
]),
|
|
'alternate_email' => new Assert\Optional(
|
|
new Assert\Email
|
|
),
|
|
],
|
|
)]
|
|
protected array $profileData = ['personal_email' => 'email@example.com'];
|
|
}
|
|
|
|
.. code-block:: yaml
|
|
|
|
# config/validator/validation.yaml
|
|
App\Entity\Author:
|
|
properties:
|
|
profile_data:
|
|
- Collection:
|
|
fields:
|
|
personal_email:
|
|
- Required:
|
|
- NotBlank: ~
|
|
- Email: ~
|
|
alternate_email:
|
|
- Optional:
|
|
- Email: ~
|
|
|
|
.. code-block:: xml
|
|
|
|
<!-- config/validator/validation.xml -->
|
|
<?xml version="1.0" encoding="UTF-8" ?>
|
|
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
|
|
|
|
<class name="App\Entity\Author">
|
|
<property name="profile_data">
|
|
<constraint name="Collection">
|
|
<option name="fields">
|
|
<value key="personal_email">
|
|
<constraint name="Required">
|
|
<constraint name="NotBlank"/>
|
|
<constraint name="Email"/>
|
|
</constraint>
|
|
</value>
|
|
<value key="alternate_email">
|
|
<constraint name="Optional">
|
|
<constraint name="Email"/>
|
|
</constraint>
|
|
</value>
|
|
</option>
|
|
</constraint>
|
|
</property>
|
|
</class>
|
|
</constraint-mapping>
|
|
|
|
.. code-block:: php
|
|
|
|
// src/Entity/Author.php
|
|
namespace App\Entity;
|
|
|
|
use Symfony\Component\Validator\Constraints as Assert;
|
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
|
|
|
class Author
|
|
{
|
|
// ...
|
|
|
|
public static function loadValidatorMetadata(ClassMetadata $metadata): void
|
|
{
|
|
$metadata->addPropertyConstraint('profileData', new Assert\Collection(
|
|
fields: [
|
|
'personal_email' => new Assert\Required([
|
|
new Assert\NotBlank(),
|
|
new Assert\Email(),
|
|
]),
|
|
'alternate_email' => new Assert\Optional(new Assert\Email()),
|
|
],
|
|
));
|
|
}
|
|
}
|
|
|
|
Even without ``allowMissingFields`` set to true, you can now omit the ``alternate_email``
|
|
property completely from the ``profileData`` array, since it is ``Optional``.
|
|
However, if the ``personal_email`` field does not exist in the array,
|
|
the ``NotBlank`` constraint will still be applied (since it is wrapped in
|
|
``Required``) and you will receive a constraint violation.
|
|
|
|
When you define groups in nested constraints they are automatically added to
|
|
the ``Collection`` constraint itself so it can be traversed for all nested
|
|
groups. Take the following example::
|
|
|
|
use Symfony\Component\Validator\Constraints as Assert;
|
|
|
|
$constraint = new Assert\Collection(
|
|
fields: [
|
|
'name' => new Assert\NotBlank(groups: 'basic'),
|
|
'email' => new Assert\NotBlank(groups: 'contact'),
|
|
],
|
|
);
|
|
|
|
This will result in the following configuration::
|
|
|
|
$constraint = new Assert\Collection(
|
|
fields: [
|
|
'name' => new Assert\Required(
|
|
constraints: new Assert\NotBlank(groups: ['basic']),
|
|
groups: ['basic', 'strict'],
|
|
),
|
|
'email' => new Assert\Required(
|
|
constraints: new Assert\NotBlank(groups: ['contact']),
|
|
groups: ['basic', 'strict'],
|
|
),
|
|
],
|
|
groups: ['basic', 'strict'],
|
|
);
|
|
|
|
The default ``allowMissingFields`` option requires the fields in all groups.
|
|
So when validating in ``contact`` group, ``$name`` can be empty but the key is
|
|
still required. If this is not the intended behavior, use the ``Optional``
|
|
constraint explicitly instead of ``Required``.
|
|
|
|
Options
|
|
-------
|
|
|
|
``allowExtraFields``
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
**type**: ``boolean`` **default**: ``false``
|
|
|
|
If this option is set to ``false`` and the underlying collection contains
|
|
one or more elements that are not included in the `fields`_ option, a validation
|
|
error will be returned. If set to ``true``, extra fields are OK.
|
|
|
|
``allowMissingFields``
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
**type**: ``boolean`` **default**: ``false``
|
|
|
|
If this option is set to ``false`` and one or more fields from the `fields`_
|
|
option are not present in the underlying collection, a validation error
|
|
will be returned. If set to ``true``, it's OK if some fields in the `fields`_
|
|
option are not present in the underlying collection.
|
|
|
|
``extraFieldsMessage``
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
**type**: ``string`` **default**: ``This field was not expected.``
|
|
|
|
The message shown if `allowExtraFields`_ is false and an extra field is
|
|
detected.
|
|
|
|
You can use the following parameters in this message:
|
|
|
|
=============== ==============================================================
|
|
Parameter Description
|
|
=============== ==============================================================
|
|
``{{ field }}`` The key of the extra field detected
|
|
=============== ==============================================================
|
|
|
|
``fields``
|
|
~~~~~~~~~~
|
|
|
|
**type**: ``array``
|
|
|
|
This option is required and is an associative array defining all of the
|
|
keys in the collection and, for each key, exactly which validator(s) should
|
|
be executed against that element of the collection.
|
|
|
|
.. include:: /reference/constraints/_groups-option.rst.inc
|
|
|
|
``missingFieldsMessage``
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
**type**: ``string`` **default**: ``This field is missing.``
|
|
|
|
The message shown if `allowMissingFields`_ is false and one or more fields
|
|
are missing from the underlying collection.
|
|
|
|
You can use the following parameters in this message:
|
|
|
|
=============== ==============================================================
|
|
Parameter Description
|
|
=============== ==============================================================
|
|
``{{ field }}`` The key of the missing field defined in ``fields``
|
|
=============== ==============================================================
|
|
|
|
.. include:: /reference/constraints/_payload-option.rst.inc
|