diff --git a/.doctor-rst.yaml b/.doctor-rst.yaml
index aea27d929db..fc13097eccc 100644
--- a/.doctor-rst.yaml
+++ b/.doctor-rst.yaml
@@ -40,18 +40,18 @@ rules:
extend_abstract_controller: ~
# no_app_bundle: ~
- # 4.x
+ # master
versionadded_directive_major_version:
- major_version: 4
+ major_version: 5
versionadded_directive_min_version:
- min_version: '4.0'
+ min_version: '5.0'
deprecated_directive_major_version:
- major_version: 4
+ major_version: 5
deprecated_directive_min_version:
- min_version: '4.0'
+ min_version: '5.0'
# do not report as violation
whitelist:
@@ -80,8 +80,12 @@ whitelist:
- '.. versionadded:: 1.6' # Flex in setup/upgrade_minor.rst
- '0 => 123' # assertion for var_dumper - components/var_dumper.rst
- '1 => "foo"' # assertion for var_dumper - components/var_dumper.rst
+ - '123,' # assertion for var_dumper - components/var_dumper.rst
+ - '"foo",' # assertion for var_dumper - components/var_dumper.rst
- '$var .= "Because of this `\xE9` octet (\\xE9),\n";'
- "`Deploying Symfony 4 Apps on Heroku`_."
- ".. _`Deploying Symfony 4 Apps on Heroku`: https://devcenter.heroku.com/articles/deploying-symfony4"
+ - "// 224, 165, 141, 224, 164, 164, 224, 165, 135])"
- '.. versionadded:: 0.2' # MercureBundle
+ - 'provides a ``loginUser()`` method to simulate logging in in your functional'
- '.. code-block:: twig'
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index bc7d6a94182..af709c9c60f 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,7 +1,7 @@
+
+
+
+
+
+
+ %env(TWILIO_DSN)%
+
+
+
+
+
+ .. code-block:: php
+
+ # config/packages/notifier.php
+ $container->loadFromExtension('framework', [
+ 'notifier' => [
+ 'texter_transports' => [
+ 'twilio' => '%env(TWILIO_DSN)%',
+ ],
+ ],
+ ]);
+
+.. _notifier-chat-channel:
+.. _notifier-chatter-dsn:
+
+Chat Channel
+~~~~~~~~~~~~
+
+The chat channel is used to send chat messages to users by using
+:class:`Symfony\\Component\\Notifier\\Chatter` classes. Symfony provides
+integration with these chat services:
+
+========== =============================== ============================================
+Service Package DSN
+========== =============================== ============================================
+Slack ``symfony/slack-notifier`` ``slack://default/ID``
+Telegram ``symfony/telegram-notifier`` ``telegram://TOKEN@default?channel=CHAT_ID``
+Mattermost ``symfony/mattermost-notifier`` ``mattermost://TOKEN@ENDPOINT?channel=CHANNEL``
+RocketChat ``symfony/rocketchat-notifier`` ``rocketchat://TOKEN@ENDPOINT?channel=CHANNEL``
+========== =============================== ============================================
+
+.. versionadded:: 5.1
+
+ The Mattermost and RocketChat integrations were introduced in Symfony
+ 5.1. The Slack DSN changed in Symfony 5.1 to use Slack Incoming
+ Webhooks instead of legacy tokens.
+
+Chatters are configured using the ``chatter_transports`` setting:
+
+.. code-block:: bash
+
+ # .env
+ SLACK_DSN=slack://default/ID
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/packages/notifier.yaml
+ framework:
+ notifier:
+ chatter_transports:
+ slack: '%env(SLACK_DSN)%'
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+ %env(SLACK_DSN)%
+
+
+
+
+
+ .. code-block:: php
+
+ # config/packages/notifier.php
+ $container->loadFromExtension('framework', [
+ 'notifier' => [
+ 'chatter_transports' => [
+ 'slack' => '%env(SLACK_DSN)%',
+ ],
+ ],
+ ]);
+
+.. _notifier-email-channel:
+
+Email Channel
+~~~~~~~~~~~~~
+
+The email channel uses the :doc:`Symfony Mailer ` to send
+notifications using the special
+:class:`Symfony\\Bridge\\Twig\\Mime\\NotificationEmail`. It is
+required to install the Twig bridge along with the Inky and CSS Inliner
+Twig extensions:
+
+.. code-block:: terminal
+
+ $ composer require symfony/twig-pack twig/cssinliner-extra twig/inky-extra
+
+After this, :ref:`configure the mailer `. You can
+also set the default "from" email address that should be used to send the
+notification emails:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/packages/mailer.yaml
+ framework:
+ mailer:
+ dsn: '%env(MAILER_DSN)%'
+ envelope:
+ sender: 'notifications@example.com'
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ # config/packages/mailer.php
+ $container->loadFromExtension('framework', [
+ 'mailer' => [
+ 'dsn' => '%env(MAILER_DSN)%',
+ 'envelope' => [
+ 'sender' => 'notifications@example.com',
+ ],
+ ],
+ ]);
+
+Configure to use Failover or Round-Robin Transports
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Besides configuring one or more separate transports, you can also use the
+special ``||`` and ``&&`` characters to implement a failover or round-robin
+transport:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/packages/notifier.yaml
+ framework:
+ notifier:
+ chatter_transports:
+ # Send notifications to Slack and use Telegram if
+ # Slack errored
+ main: '%env(SLACK_DSN)% || %env(TELEGRAM_DSN)%'
+
+ # Send notifications to the next scheduled transport calculated by round robin
+ roundrobin: '%env(SLACK_DSN)% && %env(TELEGRAM_DSN)%'
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+ %env(SLACK_DSN)% || %env(TELEGRAM_DSN)%
+
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ # config/packages/notifier.php
+ $container->loadFromExtension('framework', [
+ 'notifier' => [
+ 'chatter_transports' => [
+ // Send notifications to Slack and use Telegram if
+ // Slack errored
+ 'main' => '%env(SLACK_DSN)% || %env(TELEGRAM_DSN)%',
+
+ // Send notifications to the next scheduled transport calculated by round robin
+ 'roundrobin' => '%env(SLACK_DSN)% && %env(TELEGRAM_DSN)%',
+ ],
+ ],
+ ]);
+
+Creating & Sending Notifications
+--------------------------------
+
+To send a notification, autowire the
+:class:`Symfony\\Component\\Notifier\\NotifierInterface` (service ID
+``notifier``). This class has a ``send()`` method that allows you to send a
+:class:`Symfony\\Component\\Notifier\\Notification\\Notification` to a
+:class:`Symfony\\Component\\Notifier\\Recipient\\Recipient`::
+
+ // src/Controller/InvoiceController.php
+ namespace App\Controller;
+
+ use Symfony\Component\Notifier\Notification\Notification;
+ use Symfony\Component\Notifier\NotifierInterface;
+ use Symfony\Component\Notifier\Recipient\AdminRecipient;
+
+ class InvoiceController extends AbstractController
+ {
+ /**
+ * @Route("/invoice/create")
+ */
+ public function create(NotifierInterface $notifier)
+ {
+ // ...
+
+ // Create a Notification that has to be sent
+ // using the "email" channel
+ $notification = (new Notification('New Invoice', ['email']))
+ ->content('You got a new invoice for 15 EUR.');
+
+ // The receiver of the Notification
+ $recipient = new AdminRecipient(
+ $user->getEmail(),
+ $user->getPhonenumber()
+ );
+
+ // Send the notification to the recipient
+ $notifier->send($notification, $recipient);
+
+ // ...
+ }
+ }
+
+The ``Notification`` is created by using two arguments: the subject and
+channels. The channels specify which channel (or transport) should be used
+to send the notification. For instance, ``['email', 'sms']`` will send
+both an email and sms notification to the user. It is required to specify
+the transport when using chatters (e.g. ``['email', 'chat/telegram']``).
+
+The default notification also has a ``content()`` and ``emoji()`` method to
+set the notification content and icon.
+
+Symfony provides three types of recipients:
+
+:class:`Symfony\\Component\\Notifier\\Recipient\\NoRecipient`
+ This is the default and is useful when there is no need to have
+ information about the receiver. For example, the browser channel uses
+ the current requests's :ref:`session flashbag `;
+
+:class:`Symfony\\Component\\Notifier\\Recipient\\Recipient`
+ This contains only the email address of the user and can be used for
+ messages on the email and browser channel;
+
+:class:`Symfony\\Component\\Notifier\\Recipient\\AdminRecipient`
+ This can contain both email address and phonenumber of the user. This
+ recipient can be used for all channels (depending on whether they are
+ actually set).
+
+Configuring Channel Policies
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Instead of specifying the target channels on creation, Symfony also allows
+you to use notification importance levels. Update the configuration to
+specify what channels should be used for specific levels (using
+``channel_policy``):
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/packages/notifier.yaml
+ framework:
+ notifier:
+ # ...
+ channel_policy:
+ # Use SMS, Slack and email for urgent notifications
+ urgent: ['sms', 'chat/slack', 'email']
+
+ # Use Slack for highly important notifications
+ high: ['chat/slack']
+
+ # Use browser for medium and low notifications
+ medium: ['browser']
+ low: ['browser']
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+ sms
+ chat/slack
+ email
+
+
+ chat/slack
+
+
+ browser
+ browser
+
+
+
+
+
+ .. code-block:: php
+
+ # config/packages/notifier.php
+ $container->loadFromExtension('framework', [
+ 'notifier' => [
+ // ...
+ 'channel_policy' => [
+ // Use SMS, Slack and email for urgent notifications
+ 'urgent' => ['sms', 'chat/slack', 'email'],
+
+ // Use Slack for highly important notifications
+ 'high' => ['chat/slack'],
+
+ // Use browser for medium and low notifications
+ 'medium' => ['browser'],
+ 'low' => ['browser'],
+ ],
+ ],
+ ]);
+
+Now, whenever the notification's importance is set to "high", it will be
+sent using the Slack transport::
+
+ // ...
+ class InvoiceController extends AbstractController
+ {
+ /**
+ * @Route("/invoice/create")
+ */
+ public function invoice(NotifierInterface $notifier)
+ {
+ // ...
+
+ $notification = (new Notification('New Invoice'))
+ ->content('You got a new invoice for 15 EUR.')
+ ->importance(Notification::IMPORTANCE_HIGH);
+
+ $notifier->send($notification, new Recipient('wouter@wouterj.nl'));
+
+ // ...
+ }
+ }
+
+Customize Notifications
+-----------------------
+
+You can extend the ``Notification`` or ``Recipient`` base classes to
+customize their behavior. For instance, you can overwrite the
+``getChannels()`` method to only return ``sms`` if the invoice price is
+very high and the recipient has a phone number::
+
+ namespace App\Notifier;
+
+ use Symfony\Component\Notifier\Notification\Notification;
+ use Symfony\Component\Notifier\Recipient\Recipient;
+
+ class InvoiceNotification extends Notification
+ {
+ private $price;
+
+ public function __construct(int $price)
+ {
+ $this->price = $price;
+ }
+
+ public function getChannels(Recipient $recipient)
+ {
+ if (
+ $this->price > 10000
+ && $recipient instanceof AdminRecipient
+ && null !== $recipient->getPhone()
+ ) {
+ return ['sms'];
+ }
+
+ return ['email'];
+ }
+ }
+
+Customize Notification Messages
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each channel has its own notification interface that you can implement to
+customize the notification message. For instance, if you want to modify the
+message based on the chat service, implement
+:class:`Symfony\\Component\\Notifier\\Notification\\ChatNotificationInterface`
+and its ``asChatMessage()`` method::
+
+ // src/Notifier/InvoiceNotification.php
+ namespace App\Notifier;
+
+ use Symfony\Component\Notifier\Message\ChatMessage;
+ use Symfony\Component\Notifier\Notification\ChatNotificationInterface;
+ use Symfony\Component\Notifier\Notification\Notification;
+ use Symfony\Component\Notifier\Recipient\Recipient;
+
+ class InvoiceNotification extends Notification implements ChatNotificationInterface
+ {
+ private $price;
+
+ public function __construct(int $price)
+ {
+ $this->price = $price;
+ }
+
+ public function asChatMessage(Recipient $recipient, string $transport = null): ?ChatMessage
+ {
+ // Add a custom emoji if the message is sent to Slack
+ if ('slack' === $transport) {
+ return (new ChatMessage('You\'re invoiced '.$this->price.' EUR.'))
+ ->emoji('money');
+ }
+
+ // If you return null, the Notifier will create the ChatMessage
+ // based on this notification as it would without this method.
+ return null;
+ }
+ }
+
+The
+:class:`Symfony\\Component\\Notifier\\Notification\\SmsNotificationInterface`
+and
+:class:`Symfony\\Component\\Notifier\\Notification\\EmailNotificationInterface`
+also exists to modify messages send to those channels.
+
+Disabling Delivery
+------------------
+
+While developing (or testing), you may want to disable delivery of notifications
+entirely. You can do this by forcing Notifier to use the ``NullTransport`` for
+all configured texter and chatter transports only in the ``dev`` (and/or
+``test``) environment:
+
+.. code-block:: yaml
+
+ # config/packages/dev/notifier.yaml
+ framework:
+ notifier:
+ texter_transports:
+ twilio: 'null://null'
+ chatter_transports:
+ slack: 'null://null'
+
+.. TODO
+ - Using the message bus for asynchronous notification
+ - Describe notifier monolog handler
+ - Describe notification_on_failed_messages integration
+
+Learn more
+----------
+
+.. toctree::
+ :maxdepth: 1
+ :glob:
+
+ notifier/*
diff --git a/notifier/chatters.rst b/notifier/chatters.rst
new file mode 100644
index 00000000000..17eac35885f
--- /dev/null
+++ b/notifier/chatters.rst
@@ -0,0 +1,93 @@
+.. index::
+ single: Notifier; Chatters
+
+How to send Chat Messages
+=========================
+
+.. versionadded:: 5.0
+
+ The Notifier component was introduced in Symfony 5.0 as an
+ :doc:`experimental feature `.
+
+The :class:`Symfony\\Component\\Notifier\\ChatterInterface` class allows
+you to send messages to chat services like Slack or Telegram::
+
+ // src/Controller/CheckoutController.php
+ namespace App\Controller;
+
+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+ use Symfony\Component\Notifier\ChatterInterface;
+ use Symfony\Component\Notifier\Message\ChatMessage;
+ use Symfony\Component\Routing\Annotation\Route;
+
+ class CheckoutController extends AbstractController
+ {
+ /**
+ * @Route("/checkout/thankyou")
+ */
+ public function thankyou(ChatterInterface $chatter)
+ {
+ $message = (new ChatMessage('You got a new invoice for 15 EUR.'))
+ // if not set explicitly, the message is send to the
+ // default transport (the first one configured)
+ ->transport('slack');
+
+ $chatter->send($message);
+
+ // ...
+ }
+ }
+
+.. seealso::
+
+ Read :ref:`the main Notifier guide ` to see how
+ to configure the different transports.
+
+Adding Interactions to a Slack Message
+--------------------------------------
+
+With a Slack message, you can use the
+:class:`Symfony\\Component\\Notifier\\Bridge\\Slack\\SlackOptions` to add
+some interactive options called `Block elements`_::
+
+ use Symfony\Component\Notifier\Bridge\Slack\Block\SlackActionsBlock;
+ use Symfony\Component\Notifier\Bridge\Slack\Block\SlackDividerBlock;
+ use Symfony\Component\Notifier\Bridge\Slack\Block\SlackImageBlock;
+ use Symfony\Component\Notifier\Bridge\Slack\Block\SlackSectionBlock;
+ use Symfony\Component\Notifier\Bridge\Slack\SlackOptions;
+ use Symfony\Component\Notifier\Message\ChatMessage;
+
+ $chatMessage = new ChatMessage('Contribute To Symfony');
+
+ // Create Slack Actions Block and add some buttons
+ $contributeToSymfonyBlocks = (new SlackActionsBlock())
+ ->button(
+ 'Improve Documentation',
+ 'https://symfony.com/doc/current/contributing/documentation/standards.html',
+ 'primary'
+ )
+ ->button(
+ 'Report bugs',
+ 'https://symfony.com/doc/current/contributing/code/bugs.html',
+ 'danger'
+ );
+
+ $slackOptions = (new SlackOptions())
+ ->block((new SlackSectionBlock())
+ ->text('The Symfony Community')
+ ->accessory(
+ new SlackImageBlockElement(
+ 'https://example.com/symfony-logo.png',
+ 'Symfony'
+ )
+ )
+ )
+ ->block(new SlackDividerBlock())
+ ->block($contributeToSymfonyBlocks);
+
+ // Add the custom options to the chat message and send the message
+ $chatMessage->options($slackOptions);
+
+ $chatter->send($chatMessage);
+
+.. _`Block elements`: https://api.slack.com/reference/block-kit/block-elements
diff --git a/notifier/texters.rst b/notifier/texters.rst
new file mode 100644
index 00000000000..d4a0a91aa55
--- /dev/null
+++ b/notifier/texters.rst
@@ -0,0 +1,45 @@
+.. index::
+ single: Notifier; Texters
+
+How to send SMS Messages
+========================
+
+.. versionadded:: 5.0
+
+ The Notifier component was introduced in Symfony 5.0 as an
+ :doc:`experimental feature `.
+
+The :class:`Symfony\\Component\\Notifier\\TexterInterface` class allows
+you to send SMS messages::
+
+ // src/Controller/SecurityController.php
+ namespace App\Controller;
+
+ use Symfony\Component\Notifier\Message\SmsMessage;
+ use Symfony\Component\Notifier\TexterInterface;
+ use Symfony\Component\Routing\Annotation\Route;
+
+ class SecurityController
+ {
+ /**
+ * @Route("/login/success")
+ */
+ public function loginSuccess(TexterInterface $texter)
+ {
+ $sms = new SmsMessage(
+ // the phone number to send the SMS message to
+ '+1411111111',
+ // the message
+ 'A new login was detected!'
+ );
+
+ $texter->send($sms);
+
+ // ...
+ }
+ }
+
+.. seealso::
+
+ Read :ref:`the main Notifier guide ` to see how
+ to configure the different transports.
diff --git a/page_creation.rst b/page_creation.rst
index 4711685ae3d..43d06a5808c 100644
--- a/page_creation.rst
+++ b/page_creation.rst
@@ -52,7 +52,7 @@ random) number and prints it. To do that, create a "Controller" class and a
class LuckyController
{
- public function number()
+ public function number(): Response
{
$number = random_int(0, 100);
diff --git a/performance.rst b/performance.rst
index 3fd0efc43c9..b919f6a3906 100644
--- a/performance.rst
+++ b/performance.rst
@@ -16,6 +16,7 @@ application to improve its performance:
#. :ref:`Install APCu Polyfill if your server uses APC `
#. :ref:`Dump the service container into a single file `
+#. :ref:`Restrict the number of locales enabled in the application `
.. _performance-install-apcu-polyfill:
@@ -32,11 +33,6 @@ features, such as the APCu Cache adapter.
Dump the Service Container into a Single File
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. versionadded:: 4.4
-
- The ``container.dumper.inline_factories`` parameter was introduced in
- Symfony 4.4.
-
Symfony compiles the :doc:`service container ` into multiple
small files by default. Set this parameter to ``true`` to compile the entire
container into a single file, which could improve performance when using
@@ -72,6 +68,15 @@ container into a single file, which could improve performance when using
// ...
$container->setParameter('container.dumper.inline_factories', true);
+
+.. _performance-enabled-locales:
+
+Restrict the Number of Locales Enabled in the Application
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use the :ref:`framework.translator.enabled_locales `
+option to only generate the translation files actually used in your application.
+
Production Server Checklist
---------------------------
@@ -100,10 +105,6 @@ used byte code cache is `APC`_.
Use the OPcache class preloading
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. versionadded:: 4.4
-
- The feature that generates the preloading file was introduced in Symfony 4.4.
-
Starting from PHP 7.4, OPcache can compile and load classes at start-up and
make them available to all requests until the server is restarted, improving
performance significantly.
@@ -121,6 +122,10 @@ The preload file path is the same as the compiled service container but with the
; php.ini
opcache.preload=/path/to/project/var/cache/prod/srcApp_KernelProdContainer.preload.php
+Use the :ref:`container.preload ` and
+:ref:`container.no_preload ` service tags to define
+which classes should or should not be preloaded PHP.
+
.. _performance-configure-opcache:
Configure OPcache for Maximum Performance
diff --git a/reference/configuration/doctrine.rst b/reference/configuration/doctrine.rst
index 5705a50c6ee..9579ff7217b 100644
--- a/reference/configuration/doctrine.rst
+++ b/reference/configuration/doctrine.rst
@@ -222,33 +222,35 @@ Keep in mind that you can't use both syntaxes at the same time.
Caching Drivers
~~~~~~~~~~~~~~~
-.. deprecated:: 4.4
-
- All the Doctrine caching types are deprecated since Symfony 4.4 and won't
- be available in Symfony 5.0 and higher. Replace them with either ``type: service``
- or ``type: pool`` and use any of the cache pools/services defined with
- :doc:`Symfony Cache `.
-
-The built-in types of caching drivers are: ``array``, ``apc``, ``apcu``,
-``memcache``, ``memcached``, ``redis``, ``wincache``, ``zenddata`` and ``xcache``.
-There is a special type called ``service`` which lets you define the ID of your
-own caching service.
-
-The following example shows an overview of the caching configurations:
+Use any of the existing :doc:`Symfony Cache ` pools or define new pools
+to cache each of Doctrine ORM elements (queries, results, etc.):
.. code-block:: yaml
+ # config/packages/prod/doctrine.yaml
+ framework:
+ cache:
+ pools:
+ doctrine.result_cache_pool:
+ adapter: cache.app
+ doctrine.system_cache_pool:
+ adapter: cache.system
+
doctrine:
orm:
- auto_mapping: true
- # each caching driver type defines its own config options
- metadata_cache_driver: apc
+ # ...
+ metadata_cache_driver:
+ type: pool
+ pool: doctrine.system_cache_pool
+ query_cache_driver:
+ type: pool
+ pool: doctrine.system_cache_pool
result_cache_driver:
- type: memcache
- host: localhost
- port: 11211
- instance_class: Memcache
- # the 'service' type requires to define the 'id' option too
+ type: pool
+ pool: doctrine.result_cache_pool
+
+ # in addition to Symfony Cache pools, you can also use the
+ # 'type: service' option to use any service as the cache
query_cache_driver:
type: service
id: App\ORM\MyCacheService
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 456fd5298a4..6c64626f07a 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -221,22 +221,13 @@ Configuration
* `storage_id`_
* `use_cookies`_
-* `templating`_
-
- * :ref:`cache `
- * `engines`_
- * :ref:`form `
-
- * :ref:`resources `
-
- * `loaders`_
-
* `test`_
* `translator`_
* `cache_dir`_
* :ref:`default_path `
* :ref:`enabled `
+ * :ref:`enabled_locales `
* `fallbacks`_
* `formatter`_
* `logging`_
@@ -260,7 +251,6 @@ Configuration
* `endpoint`_
* `static_method`_
- * `strict_email`_
* `translation_domain`_
* `workflows`_
@@ -464,10 +454,6 @@ disallow_search_engine_index
**type**: ``boolean`` **default**: ``true`` when the debug mode is enabled, ``false`` otherwise.
-.. versionadded:: 4.3
-
- The ``disallow_search_engine_index`` option was introduced in Symfony 4.3.
-
If ``true``, Symfony adds a ``X-Robots-Tag: noindex`` HTTP tag to all responses
(unless your own app adds that header, in which case it's not modified). This
`X-Robots-Tag HTTP header`_ tells search engines to not index your web site.
@@ -604,10 +590,6 @@ error_controller
**type**: ``string`` **default**: ``error_controller``
-.. versionadded:: 4.4
-
- The ``error_controller`` option was introduced in Symfony 4.4.
-
This is the controller that is called when an exception is thrown anywhere in
your application. The default controller
(:class:`Symfony\\Component\\HttpKernel\\Controller\\ErrorController`)
@@ -689,12 +671,6 @@ hinclude_default_template
**type**: ``string`` **default**: ``null``
-.. versionadded:: 4.3
-
- The ``framework.fragments.hinclude_default_template`` option was introduced
- in Symfony 4.3. In previous Symfony versions it was defined under
- ``framework.templating.hinclude_default_template``.
-
Sets the content shown during the loading of the fragment or when JavaScript
is disabled. This can be either a template name or the content itself.
@@ -786,10 +762,6 @@ auth_ntlm
**type**: ``string``
-.. versionadded:: 4.4
-
- The ``auth_ntlm`` option was introduced in Symfony 4.4.
-
The username and password used to create the ``Authorization`` HTTP header used
in the `Microsoft NTLM authentication protocol`_. The value of this option must
follow the format ``username:password``. This authentication mechanism requires
@@ -840,10 +812,6 @@ If this option is a boolean value, the response is buffered when the value is
returned value is ``true`` (the closure receives as argument an array with the
response headers).
-.. versionadded:: 4.4
-
- The support of ``Closure`` in the ``buffer`` option was introduced in Symfony 4.4.
-
cafile
......
@@ -1004,10 +972,6 @@ max_duration
The maximum execution time, in seconds, that the request and the response are
allowed to take. A value lower than or equal to 0 means it is unlimited.
-.. versionadded:: 4.4
-
- The ``max_duration`` option was introduced in Symfony 4.4.
-
verify_host
...........
@@ -1209,6 +1173,11 @@ utf8
**type**: ``boolean`` **default**: ``false``
+.. deprecated:: 5.1
+
+ Not setting this option is deprecated since Symfony 5.1. Moreover, the
+ default value of this option will change to ``true`` in Symfony 6.0.
+
When this option is set to ``true``, the regular expressions used in the
:ref:`requirements of route parameters ` will be run
using the `utf-8 modifier`_. This will for example match any UTF-8 character
@@ -1330,7 +1299,7 @@ to the cookie specification.
cookie_samesite
...............
-**type**: ``string`` or ``null`` **default**: ``null``
+**type**: ``string`` or ``null`` **default**: ``'lax'``
It controls the way cookies are sent when the HTTP request was not originated
from the same domain the cookies are associated to. Setting this option is
@@ -1361,10 +1330,10 @@ The possible values for this option are:
cookie_secure
.............
-**type**: ``boolean`` or ``string`` **default**: ``false``
+**type**: ``boolean`` or ``null`` **default**: ``null``
This determines whether cookies should only be sent over secure connections. In
-addition to ``true`` and ``false``, there's a special ``'auto'`` value that
+addition to ``true`` and ``false``, there's a special ``null`` value that
means ``true`` for HTTPS requests and ``false`` for HTTP requests.
cookie_httponly
@@ -1909,10 +1878,11 @@ json_manifest_path
**type**: ``string`` **default**: ``null``
-The file path to a ``manifest.json`` file containing an associative array of asset
-names and their respective compiled names. A common cache-busting technique using
-a "manifest" file works by writing out assets with a "hash" appended to their
-file names (e.g. ``main.ae433f1cb.css``) during a front-end compilation routine.
+The file path or absolute URL to a ``manifest.json`` file containing an
+associative array of asset names and their respective compiled names. A common
+cache-busting technique using a "manifest" file works by writing out assets with
+a "hash" appended to their file names (e.g. ``main.ae433f1cb.css``) during a
+front-end compilation routine.
.. tip::
@@ -1933,6 +1903,8 @@ package:
assets:
# this manifest is applied to every asset (including packages)
json_manifest_path: "%kernel.project_dir%/public/build/manifest.json"
+ # you can use absolute URLs too and Symfony will download them automatically
+ # json_manifest_path: 'https://cdn.example.com/manifest.json'
packages:
foo_package:
# this package uses its own manifest (the default file is ignored)
@@ -1954,6 +1926,8 @@ package:
+
+
[
// this manifest is applied to every asset (including packages)
'json_manifest_path' => '%kernel.project_dir%/public/build/manifest.json',
+ // you can use absolute URLs too and Symfony will download them automatically
+ // 'json_manifest_path' => 'https://cdn.example.com/manifest.json',
'packages' => [
'foo_package' => [
// this package uses its own manifest (the default file is ignored)
@@ -1986,6 +1962,11 @@ package:
],
]);
+.. versionadded:: 5.1
+
+ The option to use an absolute URL in ``json_manifest_path`` was introduced
+ in Symfony 5.1.
+
.. note::
This parameter cannot be set at the same time as ``version`` or ``version_strategy``.
@@ -1997,53 +1978,58 @@ package:
If you request an asset that is *not found* in the ``manifest.json`` file, the original -
*unmodified* - asset path will be returned.
-templating
+.. note::
+
+ If an URL is set, the JSON manifest is downloaded on each request using the `http_client`_.
+
+translator
~~~~~~~~~~
-.. deprecated:: 4.3
+cache_dir
+.........
- The integration of the Templating component in FrameworkBundle has been
- deprecated since version 4.3 and will be removed in 5.0. That's why all the
- configuration options defined under ``framework.templating`` are deprecated too.
+**type**: ``string`` | ``null`` **default**: ``%kernel.cache_dir%/translations/``
-.. _reference-templating-form:
+Defines the directory where the translation cache is stored. Use ``null`` to
+disable this cache.
-form
-....
+.. _reference-translator-enabled:
-.. _reference-templating-form-resources:
+enabled
+.......
-resources
-"""""""""
+**type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation
+
+Whether or not to enable the ``translator`` service in the service container.
+
+.. _reference-translator-enabled-locales:
-**type**: ``string[]`` **default**: ``['FrameworkBundle:Form']``
+enabled_locales
+...............
-.. deprecated:: 4.3
+**type**: ``array`` **default**: ``[]`` (empty array = enable all locales)
- The integration of the Templating component in FrameworkBundle has been
- deprecated since version 4.3 and will be removed in 5.0. Form theming with
- PHP templates will no longer be supported and you'll need to use Twig instead.
+.. versionadded:: 5.1
-A list of all resources for form theming in PHP. This setting is not required
-if you're :ref:`using the Twig format for your themes `.
+ The ``enabled_locales`` option was introduced in Symfony 5.1.
-Assume you have custom global form themes in ``templates/form_themes/``, you can
-configure this like:
+Symfony applications generate by default the translation files for validation
+and security messages in all locales. If your application only uses some
+locales, use this option to restrict the files generated by Symfony and improve
+performance a bit:
.. configuration-block::
.. code-block:: yaml
- # config/packages/framework.yaml
+ # config/packages/translation.yaml
framework:
- templating:
- form:
- resources:
- - 'form_themes'
+ translator:
+ enabled_locales: ['en', 'es']
.. code-block:: xml
-
+
-
-
- form_themes
-
-
+
+ en
+ es
+
.. code-block:: php
- // config/packages/framework.php
+ // config/packages/translation.php
$container->loadFromExtension('framework', [
- 'templating' => [
- 'form' => [
- 'resources' => [
- 'form_themes',
- ],
- ],
+ 'translator' => [
+ 'enabled_locales' => ['en', 'es'],
],
]);
-.. note::
-
- The default form templates from ``FrameworkBundle:Form`` will always
- be included in the form resources.
-
-.. seealso::
-
- See :ref:`forms-theming-global` for more information.
-
-.. _reference-templating-cache:
-
-cache
-.....
-
-**type**: ``string``
-
-The path to the cache directory for templates. When this is not set, caching
-is disabled.
-
-.. note::
-
- When using Twig templating, the caching is already handled by the
- TwigBundle and doesn't need to be enabled for the FrameworkBundle.
-
-engines
-.......
-
-**type**: ``string[]`` / ``string`` **required**
-
-The Templating Engine to use. This can either be a string (when only one
-engine is configured) or an array of engines.
-
-At least one engine is required.
-
-loaders
-.......
-
-**type**: ``string[]``
-
-An array (or a string when configuring just one loader) of service ids for
-templating loaders. Templating loaders are used to find and load templates
-from a resource (e.g. a filesystem or database). Templating loaders must
-implement :class:`Symfony\\Component\\Templating\\Loader\\LoaderInterface`.
-
-translator
-~~~~~~~~~~
-
-cache_dir
-.........
-
-**type**: ``string`` | ``null`` **default**: ``%kernel.cache_dir%/translations/``
-
-.. versionadded:: 4.4
-
- The ``cache_dir`` option was introduced in Symfony 4.4.
-
-Defines the directory where the translation cache is stored. Use ``null`` to
-disable this cache.
-
-.. _reference-translator-enabled:
-
-enabled
-.......
-
-**type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation
-
-Whether or not to enable the ``translator`` service in the service container.
+If some user makes requests with a locale not included in this option, the
+application won't display any error because Symfony will display contents using
+the fallback locale.
.. _fallback:
fallbacks
.........
-**type**: ``string|array`` **default**: ``['en']``
+**type**: ``string|array`` **default**: value of `default_locale`_
This option is used when the translation key for the current locale wasn't
found.
@@ -2223,10 +2140,6 @@ throw_exception_on_invalid_property_path
**type**: ``boolean`` **default**: ``true``
-.. versionadded:: 4.3
-
- The ``throw_exception_on_invalid_property_path`` option was introduced in Symfony 4.3.
-
When enabled, the ``property_accessor`` service throws an exception when you
try to access an invalid property path of an object.
@@ -2301,10 +2214,6 @@ enabled
**type**: ``boolean`` **default**: ``true``
-.. versionadded:: 4.3
-
- The ``enabled`` option was introduced in Symfony 4.3.
-
If you set this option to ``false``, no HTTP requests will be made and the given
password will be considered valid. This is useful when you don't want or can't
make HTTP requests, such as in ``dev`` and ``test`` environments or in
@@ -2315,10 +2224,6 @@ endpoint
**type**: ``string`` **default**: ``null``
-.. versionadded:: 4.3
-
- The ``endpoint`` option was introduced in Symfony 4.3.
-
By default, the :doc:`NotCompromisedPassword `
constraint uses the public API provided by `haveibeenpwned.com`_. This option
allows to define a different, but compatible, API endpoint to make the password
@@ -2335,20 +2240,6 @@ metadata of the class. You can define an array of strings with the names of
several methods. In that case, all of them will be called in that order to load
the metadata.
-strict_email
-............
-
-**type**: ``Boolean`` **default**: ``false``
-
-.. deprecated:: 4.1
-
- The ``strict_email`` option was deprecated in Symfony 4.1. Use the new
- ``email_validation_mode`` option instead.
-
-If this option is enabled, the `egulias/email-validator`_ library will be
-used by the :doc:`/reference/constraints/Email` constraint validator. Otherwise,
-the validator uses a simple regular expression to validate email addresses.
-
email_validation_mode
.....................
@@ -2907,10 +2798,6 @@ A list of lock stores to be created by the framework extension.
],
]);
-.. versionadded:: 4.2
-
- The ``flock://`` store was introduced in Symfony 4.2.
-
.. _reference-lock-resources-name:
name
@@ -2930,7 +2817,7 @@ Name of the lock you want to create.
lock.invoice.retry_till_save.store:
class: Symfony\Component\Lock\Store\RetryTillSaveStore
decorates: lock.invoice.store
- arguments: ['@lock.invoice.retry_till_save.store.inner', 100, 50]
+ arguments: ['@.inner', 100, 50]
workflows
~~~~~~~~~
diff --git a/reference/configuration/kernel.rst b/reference/configuration/kernel.rst
index 5852927e7ad..5f52cd155e7 100644
--- a/reference/configuration/kernel.rst
+++ b/reference/configuration/kernel.rst
@@ -12,12 +12,17 @@ Configuration
-------------
* `Charset`_
-* `Kernel Name`_
* `Project Directory`_
* `Cache Directory`_
* `Log Directory`_
* `Container Build Time`_
+In previous Symfony versions there was another configuration option to define
+the "kernel name", which is only important when
+:doc:`using applications with multiple kernels `.
+If you need a unique ID for your kernels use the ``kernel.container_class``
+parameter or the ``Kernel::getContainerClass()`` method.
+
.. _configuration-kernel-charset:
Charset
@@ -44,29 +49,6 @@ charset::
}
}
-Kernel Name
-~~~~~~~~~~~
-
-**type**: ``string`` **default**: ``src`` (i.e. the directory name holding
-the kernel class)
-
-.. deprecated:: 4.2
-
- The ``kernel.name`` parameter and the ``Kernel::getName()`` method were
- deprecated in Symfony 4.2. If you need a unique ID for your kernels use the
- ``kernel.container_class`` parameter or the ``Kernel::getContainerClass()`` method.
-
-The name of the kernel isn't usually directly important - it's used in the
-generation of cache files - and you probably will only change it when
-:doc:`using applications with multiple kernels `.
-
-This value is exposed via the ``kernel.name`` configuration parameter and the
-:method:`Symfony\\Component\\HttpKernel\\Kernel::getName` method.
-
-To change this setting, override the ``getName()`` method. Alternatively, move
-your kernel into a different directory. For example, if you moved the kernel
-into a ``foo/`` directory (instead of ``src/``), the kernel name will be ``foo``.
-
.. _configuration-kernel-project-directory:
Project Directory
@@ -121,11 +103,6 @@ Log Directory
**type**: ``string`` **default**: ``$this->getProjectDir()/var/log``
-.. deprecated:: 4.2
-
- The ``kernel.log_dir`` parameter was deprecated in Symfony 4.2,
- use ``kernel.logs_dir`` instead.
-
This returns the absolute path of the log directory of your Symfony project.
It's calculated automatically based on the current
:ref:`environment `.
diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst
index c3f66e1c5f5..2392181cac5 100644
--- a/reference/configuration/security.rst
+++ b/reference/configuration/security.rst
@@ -71,10 +71,6 @@ When set to ``lazy``, Symfony loads the user (and starts the session) only if
the application actually accesses the ``User`` object (e.g. via a ``is_granted()``
call in a template or ``isGranted()`` in a controller or service).
-.. versionadded:: 4.4
-
- The ``lazy`` value of the ``anonymous`` option was introduced in Symfony 4.4.
-
erase_credentials
~~~~~~~~~~~~~~~~~
@@ -159,7 +155,6 @@ encoding algorithm. Also, each algorithm defines different config options:
algorithm: 'sodium'
memory_cost: 16384 # Amount in KiB. (16384 = 16 MiB)
time_cost: 2 # Number of iterations
- threads: 4 # Number of parallel threads
# MessageDigestPasswordEncoder encoder using SHA512 hashing with default options
AppBundle\Entity\User: 'sha512'
@@ -172,7 +167,9 @@ encoding algorithm. Also, each algorithm defines different config options:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services
- https://symfony.com/schema/dic/services/services-1.0.xsd">
+ https://symfony.com/schema/dic/services/services-1.0.xsd
+ http://symfony.com/schema/dic/security
+ https://symfony.com/schema/dic/security/security-1.0.xsd">
@@ -197,14 +194,12 @@ encoding algorithm. Also, each algorithm defines different config options:
+ time_cost: number of iterations -->
@@ -244,7 +239,6 @@ encoding algorithm. Also, each algorithm defines different config options:
'algorithm' => 'sodium',
'memory_cost' => 16384, // Amount in KiB. (16384 = 16 MiB)
'time_cost' => 2, // Number of iterations
- 'threads' => 4, // Number of parallel threads
],
// MessageDigestPasswordEncoder encoder using SHA512 hashing with default options
@@ -254,17 +248,6 @@ encoding algorithm. Also, each algorithm defines different config options:
],
]);
-.. deprecated:: 4.3
-
- The ``threads`` configuration option was deprecated in Symfony 4.3. No
- alternative is provided because starting from Symfony 5.0 this value will be
- hardcoded to ``1`` (one thread).
-
-.. versionadded:: 4.3
-
- The ``sodium`` algorithm was introduced in Symfony 4.3. In previous Symfony
- versions it was called ``argon2i``.
-
.. tip::
You can also create your own password encoders as services and you can even
@@ -277,11 +260,6 @@ encoding algorithm. Also, each algorithm defines different config options:
Using the Sodium Password Encoder
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. versionadded:: 4.3
-
- The ``SodiumPasswordEncoder`` was introduced in Symfony 4.3. In previous
- Symfony versions it was called ``Argon2iPasswordEncoder``.
-
It uses the `Argon2 key derivation function`_ and it's the encoder recommended
by Symfony. Argon2 support was introduced in PHP 7.2, but if you use an earlier
PHP version, you can install the `libsodium`_ PHP extension.
@@ -363,7 +341,9 @@ application:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services
- https://symfony.com/schema/dic/services/services-1.0.xsd">
+ https://symfony.com/schema/dic/services/services-1.0.xsd
+ http://symfony.com/schema/dic/security
+ https://symfony.com/schema/dic/security/security-1.0.xsd">
@@ -558,28 +538,18 @@ The ``invalidate_session`` option allows to redefine this behavior. Set this
option to ``false`` in every firewall and the user will only be logged out from
the current firewall and not the other ones.
-logout_on_user_change
-~~~~~~~~~~~~~~~~~~~~~
-
-**type**: ``boolean`` **default**: ``true``
-
-.. deprecated:: 4.1
-
- The ``logout_on_user_change`` option was deprecated in Symfony 4.1.
-
-If ``false`` this option makes Symfony to not trigger a logout when the user has
-changed. Doing that is deprecated, so this option should be set to ``true`` or
-unset to avoid getting deprecation messages.
-
-The user is considered to have changed when the user class implements
-:class:`Symfony\\Component\\Security\\Core\\User\\EquatableInterface` and the
-``isEqualTo()`` method returns ``false``. Also, when any of the properties
-required by the :class:`Symfony\\Component\\Security\\Core\\User\\UserInterface`
-(like the username, password or salt) changes.
+.. _reference-security-logout-success-handler:
success_handler
~~~~~~~~~~~~~~~
+.. deprecated:: 5.1
+
+ This option is deprecated since Symfony 5.1. Register an
+ :doc:`event listener ` on the
+ :class:`Symfony\\Component\\Security\\Http\\Event\\LogoutEvent`
+ instead.
+
**type**: ``string`` **default**: ``'security.logout.success_handler'``
The service ID used for handling a successful logout. The service must implement
@@ -705,7 +675,9 @@ multiple firewalls, the "context" could actually be shared:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services
- https://symfony.com/schema/dic/services/services-1.0.xsd">
+ https://symfony.com/schema/dic/services/services-1.0.xsd
+ http://symfony.com/schema/dic/security
+ https://symfony.com/schema/dic/security/security-1.0.xsd">
diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst
index 1d11db3e3da..e00d7f63958 100644
--- a/reference/configuration/twig.rst
+++ b/reference/configuration/twig.rst
@@ -42,7 +42,6 @@ Configuration
* `debug`_
* `default_path`_
-* `exception_controller`_
* `form_themes`_
* `globals`_
* `number_format`_
@@ -196,29 +195,6 @@ The path to the directory where Symfony will look for the application Twig
templates by default. If you store the templates in more than one directory, use
the :ref:`paths ` option too.
-.. _config-twig-exception-controller:
-
-exception_controller
-~~~~~~~~~~~~~~~~~~~~
-
-**type**: ``string`` **default**: ``twig.controller.exception:showAction``
-
-.. deprecated:: 4.4
-
- The ``exception_controller`` configuration option was deprecated in Symfony 4.4.
- Set it to ``null`` and use the new ``error_controller`` option under ``framework``
- configuration instead.
-
-This is the controller that is activated after an exception is thrown anywhere
-in your application. The default controller
-(:class:`Symfony\\Bundle\\TwigBundle\\Controller\\ExceptionController`)
-is what's responsible for rendering specific templates under different error
-conditions (see :doc:`/controller/error_pages`). Modifying this
-option is advanced. If you need to customize an error page you should use
-the previous link. If you need to perform some behavior on an exception,
-you should add an :doc:`event listener ` to the
-:ref:`kernel.exception event `.
-
.. _config-twig-form-themes:
form_themes
diff --git a/reference/constraints.rst b/reference/constraints.rst
index 317a836e396..1aeaca354e7 100644
--- a/reference/constraints.rst
+++ b/reference/constraints.rst
@@ -14,9 +14,11 @@ Validation Constraints Reference
constraints/Type
constraints/Email
+ constraints/ExpressionLanguageSyntax
constraints/Length
constraints/Url
constraints/Regex
+ constraints/Hostname
constraints/Ip
constraints/Uuid
constraints/Json
@@ -62,6 +64,9 @@ Validation Constraints Reference
constraints/Isbn
constraints/Issn
+ constraints/AtLeastOneOf
+ constraints/Sequentially
+ constraints/Compound
constraints/Callback
constraints/Expression
constraints/All
diff --git a/reference/constraints/AtLeastOneOf.rst b/reference/constraints/AtLeastOneOf.rst
new file mode 100644
index 00000000000..6a48c44a4fd
--- /dev/null
+++ b/reference/constraints/AtLeastOneOf.rst
@@ -0,0 +1,196 @@
+AtLeastOneOf
+============
+
+This constraint checks that the value satisfies at least one of the given
+constraints. The validation stops as soon as one constraint is satisfied.
+
+.. versionadded:: 5.1
+
+ The ``AtLeastOneOf`` constraint was introduced in Symfony 5.1.
+
+========== ===================================================================
+Applies to :ref:`property or method `
+Options - `constraints`_
+ - `includeInternalMessages`_
+ - `message`_
+ - `messageCollection`_
+ - `groups`_
+ - `payload`_
+Class :class:`Symfony\\Component\\Validator\\Constraints\\AtLeastOneOf`
+Validator :class:`Symfony\\Component\\Validator\\Constraints\\AtLeastOneOfValidator`
+========== ===================================================================
+
+Basic Usage
+-----------
+
+The following constraints ensure that:
+
+* the ``password`` of a ``Student`` either contains ``#`` or is at least ``10``
+ characters long;
+* the ``grades`` of a ``Student`` is an array which contains at least ``3``
+ elements or that each element is greater than or equal to ``5``.
+
+.. configuration-block::
+
+ .. code-block:: php-annotations
+
+ // src/Entity/Student.php
+ namespace App\Entity;
+
+ use Symfony\Component\Validator\Constraints as Assert;
+
+ class Student
+ {
+ /**
+ * @Assert\AtLeastOneOf({
+ * @Assert\Regex("/#/"),
+ * @Assert\Length(min=10)
+ * })
+ */
+ protected $password;
+
+ /**
+ * @Assert\AtLeastOneOf({
+ * @Assert\Count(min=3),
+ * @Assert\All(
+ * @Assert\GreaterThanOrEqual(5)
+ * )
+ * })
+ */
+ protected $grades;
+ }
+
+ .. code-block:: yaml
+
+ # config/validator/validation.yaml
+ App\Entity\Student:
+ properties:
+ password:
+ - AtLeastOneOf:
+ - Regex: '/#/'
+ - Length:
+ min: 10
+ grades:
+ - AtLeastOneOf:
+ - Count:
+ min: 3
+ - All:
+ - GreaterThanOrEqual: 5
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
3
+
+
+
+
+ 5
+
+
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ // src/Entity/Student.php
+ namespace App\Entity;
+
+ use Symfony\Component\Validator\Constraints as Assert;
+ use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+ class Student
+ {
+ public static function loadValidatorMetadata(ClassMetadata $metadata)
+ {
+ $metadata->addPropertyConstraint('password', new Assert\AtLeastOneOf([
+ 'constraints' => [
+ new Assert\Regex(['pattern' => '/#/']),
+ new Assert\Length(['min' => 10]),
+ ],
+ ]));
+
+ $metadata->addPropertyConstraint('grades', new Assert\AtLeastOneOf([
+ 'constraints' => [
+ new Assert\Count(['min' => 3]),
+ new Assert\All([
+ 'constraints' => [
+ new Assert\GreaterThanOrEqual(['value' => 5]),
+ ],
+ ]),
+ ],
+ ]));
+ }
+ }
+
+Options
+-------
+
+constraints
+~~~~~~~~~~~
+
+**type**: ``array`` [:ref:`default option `]
+
+This required option is the array of validation constraints from which at least one of
+has to be satisfied in order for the validation to succeed.
+
+includeInternalMessages
+~~~~~~~~~~~~~~~~~~~~~~~
+
+**type**: ``bool`` **default**: ``true``
+
+If set to ``true``, the message that is shown if the validation fails,
+will include the list of messages for the internal constraints. See option
+`message`_ for an example.
+
+message
+~~~~~~~
+
+**type**: ``string`` **default**: ``This value should satisfy at least one of the following constraints:``
+
+This is the intro of the message that will be shown if the validation fails. By default,
+it will be followed by the list of messages for the internal constraints
+(configurable by `includeInternalMessages`_ option) . For example,
+if the above ``grades`` property fails to validate, the message will be
+``This value should satisfy at least one of the following constraints:
+[1] This collection should contain 3 elements or more.
+[2] Each element of this collection should satisfy its own set of constraints.``
+
+messageCollection
+~~~~~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``Each element of this collection should satisfy its own set of constraints.``
+
+This is the message that will be shown if the validation fails
+and the internal constraint is either :doc:`/reference/constraints/All`
+or :doc:`/reference/constraints/Collection`. See option `message`_ for an example.
+
+.. include:: /reference/constraints/_groups-option.rst.inc
+
+.. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/Bic.rst b/reference/constraints/Bic.rst
index 6496ae63d54..029a322e294 100644
--- a/reference/constraints/Bic.rst
+++ b/reference/constraints/Bic.rst
@@ -92,10 +92,6 @@ iban
**type**: ``string`` **default**: ``null``
-.. versionadded:: 4.3
-
- The ``iban`` option was introduced in Symfony 4.3.
-
An IBAN value to validate that its country code is the same as the BIC's one.
ibanMessage
@@ -103,10 +99,6 @@ ibanMessage
**type**: ``string`` **default**: ``This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.``
-.. versionadded:: 4.3
-
- The ``ibanMessage`` option was introduced in Symfony 4.3.
-
The default message supplied when the value does not pass the combined BIC/IBAN check.
ibanPropertyPath
@@ -114,10 +106,6 @@ ibanPropertyPath
**type**: ``string`` **default**: ``null``
-.. versionadded:: 4.3
-
- The ``ibanPropertyPath`` option was introduced in Symfony 4.3.
-
It defines the object property whose value stores the IBAN used to check the BIC with.
For example, if you want to compare the ``$bic`` property of some object
diff --git a/reference/constraints/CardScheme.rst b/reference/constraints/CardScheme.rst
index 6362d9932ee..6adfe62d893 100644
--- a/reference/constraints/CardScheme.rst
+++ b/reference/constraints/CardScheme.rst
@@ -138,10 +138,6 @@ Valid values are:
* ``UATP``
* ``VISA``
-.. versionadded:: 4.3
-
- The ``UATP`` and ``MIR`` number schemes were introduced in Symfony 4.3.
-
For more information about the used schemes, see
`Wikipedia: Issuer identification number (IIN)`_.
diff --git a/reference/constraints/Choice.rst b/reference/constraints/Choice.rst
index b1407c8add0..707bfd11bc5 100644
--- a/reference/constraints/Choice.rst
+++ b/reference/constraints/Choice.rst
@@ -322,10 +322,6 @@ Parameter Description
``{{ value }}`` The current (invalid) value
================= ============================================================
-.. versionadded:: 4.3
-
- The ``{{ choices }}`` parameter was introduced in Symfony 4.3.
-
message
~~~~~~~
@@ -371,10 +367,6 @@ Parameter Description
``{{ value }}`` The current (invalid) value
================= ============================================================
-.. versionadded:: 4.3
-
- The ``{{ choices }}`` parameter was introduced in Symfony 4.3.
-
multiple
~~~~~~~~
diff --git a/reference/constraints/Compound.rst b/reference/constraints/Compound.rst
new file mode 100644
index 00000000000..8552058708c
--- /dev/null
+++ b/reference/constraints/Compound.rst
@@ -0,0 +1,111 @@
+Compound
+========
+
+To the contrary to the other constraints, this constraint cannot be used on its own.
+Instead, it allows you to create your own set of reusable constraints, representing
+rules to use consistently across your application, by extending the constraint.
+
+.. versionadded:: 5.1
+
+ The ``Compound`` constraint was introduced in Symfony 5.1.
+
+========== ===================================================================
+Applies to :ref:`class ` or :ref:`property or method `
+Options - `groups`_
+ - `payload`_
+Class :class:`Symfony\\Component\\Validator\\Constraints\\Compound`
+Validator :class:`Symfony\\Component\\Validator\\Constraints\\CompoundValidator`
+========== ===================================================================
+
+Basic Usage
+-----------
+
+Suppose that you have different places where a user password must be validated,
+you can create your own named set or requirements to be reused consistently everywhere::
+
+ // src/Validator/Constraints/PasswordRequirements.php
+ namespace App\Validator\Constraints;
+
+ use Symfony\Component\Validator\Compound;
+ use Symfony\Component\Validator\Constraints as Assert;
+
+ /**
+ * @Annotation
+ */
+ class PasswordRequirements extends Compound
+ {
+ protected function getConstraints(array $options): array
+ {
+ return [
+ new Assert\NotBlank(),
+ new Assert\Type('string'),
+ new Assert\Length(['min' => 12]),
+ new Assert\NotCompromisedPassword(),
+ ];
+ }
+ }
+
+You can now use it anywhere you need it:
+
+.. configuration-block::
+
+ .. code-block:: php-annotations
+
+ // src/User/RegisterUser.php
+ namespace App\User;
+
+ use App\Validator\Constraints as AcmeAssert;
+
+ class RegisterUser
+ {
+ /**
+ * @AcmeAssert\PasswordRequirements()
+ */
+ public $password;
+ }
+
+ .. code-block:: yaml
+
+ # config/validator/validation.yaml
+ App\User\RegisterUser:
+ properties:
+ password:
+ - App\Validator\Constraints\PasswordRequirements: ~
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ // src/User/RegisterUser.php
+ namespace App\User;
+
+ use App\Validator\Constraints as AcmeAssert;
+ use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+ class RegisterUser
+ {
+ public static function loadValidatorMetadata(ClassMetadata $metadata)
+ {
+ $metadata->addPropertyConstraint('password', new AcmeAssert\PasswordRequirements());
+ }
+ }
+
+Options
+-------
+
+.. include:: /reference/constraints/_groups-option.rst.inc
+
+.. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/Count.rst b/reference/constraints/Count.rst
index 2ff99b5adbb..4ce4691c6c9 100644
--- a/reference/constraints/Count.rst
+++ b/reference/constraints/Count.rst
@@ -6,7 +6,9 @@ Countable) element count is *between* some minimum and maximum value.
========== ===================================================================
Applies to :ref:`property or method `
-Options - `exactMessage`_
+Options - `divisibleBy`_
+ - `divisibleByMessage`_
+ - `exactMessage`_
- `groups`_
- `max`_
- `maxMessage`_
@@ -101,6 +103,44 @@ you might add the following:
Options
-------
+divisibleBy
+~~~~~~~~~~~
+
+**type**: ``integer`` **default**: null
+
+.. versionadded:: 5.1
+
+ The ``divisibleBy`` option was introduced in Symfony 5.1.
+
+Validates that the number of elements of the given collection is divisible by
+a certain number.
+
+.. seealso::
+
+ If you need to validate that other types of data different from collections
+ are divisible by a certain number, use the
+ :doc:`DivisibleBy ` constraint.
+
+divisibleByMessage
+~~~~~~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``The number of elements in this collection should be a multiple of {{ compared_value }}.``
+
+.. versionadded:: 5.1
+
+ The ``divisibleByMessage`` option was introduced in Symfony 5.1.
+
+The message that will be shown if the number of elements of the given collection
+is not divisible by the number defined in the ``divisibleBy`` option.
+
+You can use the following parameters in this message:
+
+======================== ===================================================
+Parameter Description
+======================== ===================================================
+``{{ compared_value }}`` The number configured in the ``divisibleBy`` option
+======================== ===================================================
+
exactMessage
~~~~~~~~~~~~
diff --git a/reference/constraints/Country.rst b/reference/constraints/Country.rst
index 4582a930cad..744de6dd0fb 100644
--- a/reference/constraints/Country.rst
+++ b/reference/constraints/Country.rst
@@ -5,7 +5,8 @@ Validates that a value is a valid `ISO 3166-1 alpha-2`_ country code.
========== ===================================================================
Applies to :ref:`property or method `
-Options - `groups`_
+Options - `alpha3`_
+ - `groups`_
- `message`_
- `payload`_
Class :class:`Symfony\\Component\\Validator\\Constraints\\Country`
@@ -76,6 +77,19 @@ Basic Usage
Options
-------
+alpha3
+~~~~~~
+
+.. versionadded:: 5.1
+
+ The ``alpha3`` option was introduced in Symfony 5.1.
+
+**type**: ``boolean`` **default**: ``false``
+
+If this option is ``true``, the constraint checks that the value is a
+`ISO 3166-1 alpha-3`_ three-letter code (e.g. France = ``FRA``) instead
+of the default `ISO 3166-1 alpha-2`_ two-letter code (e.g. France = ``FR``).
+
.. include:: /reference/constraints/_groups-option.rst.inc
``message``
@@ -96,3 +110,5 @@ Parameter Description
.. include:: /reference/constraints/_payload-option.rst.inc
.. _`ISO 3166-1 alpha-2`: https://en.wikipedia.org/wiki/ISO_3166-1#Current_codes
+.. _`ISO 3166-1 alpha-3`: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3#Current_codes
+
diff --git a/reference/constraints/DivisibleBy.rst b/reference/constraints/DivisibleBy.rst
index c93052a248a..4503959aa57 100644
--- a/reference/constraints/DivisibleBy.rst
+++ b/reference/constraints/DivisibleBy.rst
@@ -3,6 +3,12 @@ DivisibleBy
Validates that a value is divisible by another value, defined in the options.
+.. seealso::
+
+ If you need to validate that the number of elements in a collection is
+ divisible by a certain number, use the :doc:`Count `
+ constraint with the ``divisibleBy`` option.
+
========== ===================================================================
Applies to :ref:`property or method `
Options - `groups`_
diff --git a/reference/constraints/Email.rst b/reference/constraints/Email.rst
index 5b149f0bf5f..ce8d428858a 100644
--- a/reference/constraints/Email.rst
+++ b/reference/constraints/Email.rst
@@ -6,9 +6,7 @@ cast to a string before being validated.
========== ===================================================================
Applies to :ref:`property or method `
-Options - `checkHost`_
- - `checkMX`_
- - `groups`_
+Options - `groups`_
- `message`_
- `mode`_
- `normalizer`_
@@ -33,8 +31,7 @@ Basic Usage
{
/**
* @Assert\Email(
- * message = "The email '{{ value }}' is not a valid email.",
- * checkMX = true
+ * message = "The email '{{ value }}' is not a valid email."
* )
*/
protected $email;
@@ -48,7 +45,6 @@ Basic Usage
email:
- Email:
message: The email "{{ value }}" is not a valid email.
- checkMX: true
.. code-block:: xml
@@ -62,7 +58,6 @@ Basic Usage
The email "{{ value }}" is not a valid email.
-
true
@@ -82,7 +77,6 @@ Basic Usage
{
$metadata->addPropertyConstraint('email', new Assert\Email([
'message' => 'The email "{{ value }}" is not a valid email.',
- 'checkMX' => true,
]));
}
}
@@ -92,36 +86,6 @@ Basic Usage
Options
-------
-checkHost
-~~~~~~~~~
-
-**type**: ``boolean`` **default**: ``false``
-
-.. deprecated:: 4.2
-
- This option was deprecated in Symfony 4.2.
-
-If true, then the :phpfunction:`checkdnsrr` PHP function will be used to
-check the validity of the MX *or* the A *or* the AAAA record of the host
-of the given email.
-
-checkMX
-~~~~~~~
-
-**type**: ``boolean`` **default**: ``false``
-
-.. deprecated:: 4.2
-
- This option was deprecated in Symfony 4.2.
-
-If true, then the :phpfunction:`checkdnsrr` PHP function will be used to
-check the validity of the MX record of the host of the given email.
-
-.. caution::
-
- This option is not reliable because it depends on the network conditions
- and some valid servers refuse to respond to those requests.
-
.. include:: /reference/constraints/_groups-option.rst.inc
message
diff --git a/reference/constraints/ExpressionLanguageSyntax.rst b/reference/constraints/ExpressionLanguageSyntax.rst
new file mode 100644
index 00000000000..2ca0355dfaf
--- /dev/null
+++ b/reference/constraints/ExpressionLanguageSyntax.rst
@@ -0,0 +1,129 @@
+ExpressionLanguageSyntax
+========================
+
+This constraint checks that the value is valid as an `ExpressionLanguage`_
+expression.
+
+.. versionadded:: 5.1
+
+ The ``ExpressionLanguageSyntax`` constraint was introduced in Symfony 5.1.
+
+========== ===================================================================
+Applies to :ref:`property or method `
+Options - `allowedVariables`_
+ - `groups`_
+ - `message`_
+ - `payload`_
+Class :class:`Symfony\\Component\\Validator\\Constraints\\ExpressionLanguageSyntax`
+Validator :class:`Symfony\\Component\\Validator\\Constraints\\ExpressionLanguageSyntaxValidator`
+========== ===================================================================
+
+Basic Usage
+-----------
+
+The following constraints ensure that:
+
+* the ``promotion`` property stores a value which is valid as an
+ ExpressionLanguage expression;
+* the ``shippingOptions`` property also ensures that the expression only uses
+ certain variables.
+
+.. configuration-block::
+
+ .. code-block:: php-annotations
+
+ // src/Entity/Order.php
+ namespace App\Entity;
+
+ use Symfony\Component\Validator\Constraints as Assert;
+
+ class Order
+ {
+ /**
+ * @Assert\ExpressionLanguageSyntax()
+ */
+ protected $promotion;
+
+ /**
+ * @Assert\ExpressionLanguageSyntax(
+ * allowedVariables = ['user', 'shipping_centers']
+ * )
+ */
+ protected $shippingOptions;
+ }
+
+ .. code-block:: yaml
+
+ # config/validator/validation.yaml
+ App\Entity\Order:
+ properties:
+ promotion:
+ - ExpressionLanguageSyntax: ~
+ shippingOptions:
+ - ExpressionLanguageSyntax:
+ allowedVariables: ['user', 'shipping_centers']
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
['user', 'shipping_centers']
+
+
+
+
+
+ .. code-block:: php
+
+ // src/Entity/Student.php
+ namespace App\Entity;
+
+ use Symfony\Component\Validator\Constraints as Assert;
+ use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+ class Order
+ {
+ public static function loadValidatorMetadata(ClassMetadata $metadata)
+ {
+ $metadata->addPropertyConstraint('promotion', new Assert\ExpressionLanguageSyntax());
+
+ $metadata->addPropertyConstraint('shippingOptions', new Assert\ExpressionLanguageSyntax([
+ 'allowedVariables' => ['user', 'shipping_centers'],
+ ]));
+ }
+ }
+
+Options
+-------
+
+allowedVariables
+~~~~~~~~~~~~~~~~
+
+**type**: ``array`` or ``null`` **default**: ``null``
+
+If this option is defined, the expression can only use the variables whose names
+are included in this option. Unset this option or set its value to ``null`` to
+allow any variables.
+
+.. include:: /reference/constraints/_groups-option.rst.inc
+
+message
+~~~~~~~
+
+**type**: ``string`` **default**: ``This value should be a valid expression.``
+
+This is the message displayed when the validation fails.
+
+.. include:: /reference/constraints/_payload-option.rst.inc
+
+.. _`ExpressionLanguage`: https://symfony.com/components/ExpressionLanguage
diff --git a/reference/constraints/File.rst b/reference/constraints/File.rst
index 8c77fb008cb..f1a27ac8f20 100644
--- a/reference/constraints/File.rst
+++ b/reference/constraints/File.rst
@@ -252,10 +252,6 @@ You can find a list of existing mime types on the `IANA website`_.
(i.e. the form type is not defined explicitly in the ``->add()`` method of
the form builder) and when the field doesn't define its own ``accept`` value.
- .. versionadded:: 4.4
-
- This feature was introduced in Symfony 4.4.
-
mimeTypesMessage
~~~~~~~~~~~~~~~~
diff --git a/reference/constraints/Hostname.rst b/reference/constraints/Hostname.rst
new file mode 100644
index 00000000000..4cbe606ccb4
--- /dev/null
+++ b/reference/constraints/Hostname.rst
@@ -0,0 +1,135 @@
+Hostname
+========
+
+This constraint ensures that the given value is a valid host name (internally it
+uses the ``FILTER_VALIDATE_DOMAIN`` option of the :phpfunction:`filter_var` PHP
+function).
+
+.. versionadded:: 5.1
+
+ The ``Hostname`` constraint was introduced in Symfony 5.1.
+
+========== ===================================================================
+Applies to :ref:`property or method `
+Options - `groups`_
+ - `message`_
+ - `payload`_
+ - `requireTld`_
+Class :class:`Symfony\\Component\\Validator\\Constraints\\Hostname`
+Validator :class:`Symfony\\Component\\Validator\\Constraints\\HostnameValidator`
+========== ===================================================================
+
+Basic Usage
+-----------
+
+To use the Hostname validator, apply it to a property on an object that
+will contain a host name.
+
+.. configuration-block::
+
+ .. code-block:: php-annotations
+
+ // src/Entity/ServerSettings.php
+ namespace App\Entity;
+
+ use Symfony\Component\Validator\Constraints as Assert;
+
+ class ServerSettings
+ {
+ /**
+ * @Assert\Hostname(message="The server name must be a valid hostname.")
+ */
+ protected $name;
+ }
+
+ .. code-block:: yaml
+
+ # config/validator/validation.yaml
+ App\Entity\ServerSettings:
+ properties:
+ name:
+ - Hostname:
+ message: The server name must be a valid hostname.
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
The server name must be a valid hostname.
+
+
+
+
+
+ .. code-block:: php
+
+ // src/Entity/ServerSettings.php
+ namespace App\Entity;
+
+ use Symfony\Component\Validator\Constraints as Assert;
+ use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+ class ServerSettings
+ {
+ public static function loadValidatorMetadata(ClassMetadata $metadata)
+ {
+ $metadata->addPropertyConstraint('name', new Assert\Hostname([
+ 'message' => 'The server name must be a valid hostname.',
+ ]));
+ }
+ }
+
+The following top-level domains (TLD) are reserved according to `RFC 2606`_ and
+that's why hostnames containing them are not considered valid: ``.example``,
+``.invalid``, ``.localhost``, and ``.test``.
+
+.. include:: /reference/constraints/_empty-values-are-valid.rst.inc
+
+Options
+-------
+
+.. include:: /reference/constraints/_groups-option.rst.inc
+
+``message``
+~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``This value is not a valid hostname.``
+
+The default message supplied when the value is not a valid hostname.
+
+You can use the following parameters in this message:
+
+=============== ==============================================================
+Parameter Description
+=============== ==============================================================
+``{{ value }}`` The current (invalid) value
+=============== ==============================================================
+
+.. include:: /reference/constraints/_payload-option.rst.inc
+
+``requireTld``
+~~~~~~~~~~~~~~
+
+**type**: ``bool`` **default**: ``true``
+
+By default, hostnames are considered valid only when they are fully qualified
+and include their TLDs (top-level domain names). For instance, ``example.com``
+is valid but ``example`` is not.
+
+Set this option to ``false`` to not require any TLD in the hostnames.
+
+.. note::
+
+ This constraint does not validate that the given TLD value is included in
+ the `list of official top-level domains`_ (because that list is growing
+ continuously and it's hard to keep track of it).
+
+.. _`RFC 2606`: https://tools.ietf.org/html/rfc2606
+.. _`list of official top-level domains`: https://en.wikipedia.org/wiki/List_of_Internet_top-level_domains
diff --git a/reference/constraints/Language.rst b/reference/constraints/Language.rst
index 70d1e2e51cc..7d58491c416 100644
--- a/reference/constraints/Language.rst
+++ b/reference/constraints/Language.rst
@@ -6,7 +6,8 @@ Validates that a value is a valid language *Unicode language identifier*
========== ===================================================================
Applies to :ref:`property or method `
-Options - `groups`_
+Options - `alpha3`_
+ - `groups`_
- `message`_
- `payload`_
Class :class:`Symfony\\Component\\Validator\\Constraints\\Language`
@@ -77,6 +78,19 @@ Basic Usage
Options
-------
+alpha3
+~~~~~~
+
+.. versionadded:: 5.1
+
+ The ``alpha3`` option was introduced in Symfony 5.1.
+
+**type**: ``boolean`` **default**: ``false``
+
+If this option is ``true``, the constraint checks that the value is a
+`ISO 639-2`_ three-letter code (e.g. French = ``fra``) instead of the default
+`ISO 639-1`_ two-letter code (e.g. French = ``fr``).
+
.. include:: /reference/constraints/_groups-option.rst.inc
``message``
@@ -95,3 +109,6 @@ Parameter Description
=============== ==============================================================
.. include:: /reference/constraints/_payload-option.rst.inc
+
+.. _`ISO 639-1`: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
+.. _`ISO 639-2`: https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
diff --git a/reference/constraints/Length.rst b/reference/constraints/Length.rst
index 11ae53ae6b9..a74673a5354 100644
--- a/reference/constraints/Length.rst
+++ b/reference/constraints/Length.rst
@@ -117,16 +117,11 @@ Options
allowEmptyString
~~~~~~~~~~~~~~~~
-**type**: ``boolean`` **default**: ``true``
+**type**: ``boolean`` **default**: ``false``
-.. versionadded:: 4.4
-
- The ``allowEmptyString`` option was introduced in Symfony 4.4.
-
-When using the ``min`` option, it's mandatory to also define this option. If
-set to ``true``, empty strings are considered valid (which is the same behavior
-as previous Symfony versions). Set it to ``false`` to consider empty strings not
-valid.
+If set to ``true``, empty strings are considered valid (which is the same
+behavior as previous Symfony versions). The default ``false`` value considers
+empty strings not valid.
.. caution::
diff --git a/reference/constraints/Locale.rst b/reference/constraints/Locale.rst
index d7f16293b3a..dbdf0905df5 100644
--- a/reference/constraints/Locale.rst
+++ b/reference/constraints/Locale.rst
@@ -8,10 +8,13 @@ the two letter `ISO 639-1`_ *language* code (e.g. ``fr``), or the language code
followed by an underscore (``_``) and the `ISO 3166-1 alpha-2`_ *country* code
(e.g. ``fr_FR`` for French/France).
+The given locale values are *canonicalized* before validating them to avoid
+issues with wrong uppercase/lowercase values and to remove unneeded elements
+(e.g. ``FR-fr.utf8`` will be validated as ``fr_FR``).
+
========== ===================================================================
Applies to :ref:`property or method `
-Options - `canonicalize`_
- - `groups`_
+Options - `groups`_
- `message`_
- `payload`_
Class :class:`Symfony\\Component\\Validator\\Constraints\\Locale`
@@ -89,19 +92,6 @@ Basic Usage
Options
-------
-canonicalize
-~~~~~~~~~~~~
-
-**type**: ``boolean`` **default**: ``false``
-
-.. deprecated:: 4.1
-
- Using this option with value ``false`` was deprecated in Symfony 4.1 and it
- will throw an exception in Symfony 5.0. Use ``true`` instead.
-
-If ``true``, the :phpmethod:`Locale::canonicalize` method will be applied before checking
-the validity of the given locale (e.g. ``FR-fr.utf8`` is transformed into ``fr_FR``).
-
.. include:: /reference/constraints/_groups-option.rst.inc
``message``
diff --git a/reference/constraints/Negative.rst b/reference/constraints/Negative.rst
index 4e3edee87f2..7468b4bfc4a 100644
--- a/reference/constraints/Negative.rst
+++ b/reference/constraints/Negative.rst
@@ -1,10 +1,6 @@
Negative
========
-.. versionadded:: 4.3
-
- The ``Negative`` constraint was introduced in Symfony 4.3.
-
Validates that a value is a negative number. Zero is neither positive nor
negative, so you must use :doc:`/reference/constraints/NegativeOrZero` if you
want to allow zero as value.
diff --git a/reference/constraints/NegativeOrZero.rst b/reference/constraints/NegativeOrZero.rst
index 5a77a36ab67..f010acda0b1 100644
--- a/reference/constraints/NegativeOrZero.rst
+++ b/reference/constraints/NegativeOrZero.rst
@@ -1,10 +1,6 @@
NegativeOrZero
==============
-.. versionadded:: 4.3
-
- The ``NegativeOrZero`` constraint was introduced in Symfony 4.3.
-
Validates that a value is a negative number or equal to zero. If you don't
want to allow zero as value, use :doc:`/reference/constraints/Negative` instead.
diff --git a/reference/constraints/NotBlank.rst b/reference/constraints/NotBlank.rst
index 19ac9542ec9..c3c16f21eae 100644
--- a/reference/constraints/NotBlank.rst
+++ b/reference/constraints/NotBlank.rst
@@ -90,10 +90,6 @@ allowNull
If set to ``true``, ``null`` values are considered valid and won't trigger a
constraint violation.
-.. versionadded:: 4.3
-
- The ``allowNull`` option was introduced in Symfony 4.3.
-
.. include:: /reference/constraints/_groups-option.rst.inc
``message``
diff --git a/reference/constraints/NotCompromisedPassword.rst b/reference/constraints/NotCompromisedPassword.rst
index ffa9fe99d8d..6d2cb52f1aa 100644
--- a/reference/constraints/NotCompromisedPassword.rst
+++ b/reference/constraints/NotCompromisedPassword.rst
@@ -1,10 +1,6 @@
NotCompromisedPassword
======================
-.. versionadded:: 4.3
-
- The ``NotCompromisedPassword`` constraint was introduced in Symfony 4.3.
-
Validates that the given password has not been compromised by checking that it is
not included in any of the public data breaches tracked by `haveibeenpwned.com`_.
diff --git a/reference/constraints/Positive.rst b/reference/constraints/Positive.rst
index bfed77a763c..af76f205e53 100644
--- a/reference/constraints/Positive.rst
+++ b/reference/constraints/Positive.rst
@@ -1,10 +1,6 @@
Positive
========
-.. versionadded:: 4.3
-
- The ``Positive`` constraint was introduced in Symfony 4.3.
-
Validates that a value is a positive number. Zero is neither positive nor
negative, so you must use :doc:`/reference/constraints/PositiveOrZero` if you
want to allow zero as value.
diff --git a/reference/constraints/PositiveOrZero.rst b/reference/constraints/PositiveOrZero.rst
index cc592f824c6..ea762e78f90 100644
--- a/reference/constraints/PositiveOrZero.rst
+++ b/reference/constraints/PositiveOrZero.rst
@@ -1,10 +1,6 @@
PositiveOrZero
==============
-.. versionadded:: 4.3
-
- The ``PositiveOrZero`` constraint was introduced in Symfony 4.3.
-
Validates that a value is a positive number or equal to zero. If you don't
want to allow zero as value, use :doc:`/reference/constraints/Positive` instead.
diff --git a/reference/constraints/Range.rst b/reference/constraints/Range.rst
index 5743d8d04ef..6e7fc8d7f86 100644
--- a/reference/constraints/Range.rst
+++ b/reference/constraints/Range.rst
@@ -363,11 +363,7 @@ maxPropertyPath
**type**: ``string``
-.. versionadded:: 4.4
-
- The ``maxPropertyPath`` option was introduced in Symfony 4.4.
-
-It defines the object property whose value is used as `max`_ option.
+It defines the object property whose value is used as ``max`` option.
For example, if you want to compare the ``$submittedDate`` property of some object
with regard to the ``$deadline`` property of the same object, use
@@ -411,11 +407,7 @@ minPropertyPath
**type**: ``string``
-.. versionadded:: 4.4
-
- The ``minPropertyPath`` option was introduced in Symfony 4.4.
-
-It defines the object property whose value is used as `min`_ option.
+It defines the object property whose value is used as ``min`` option.
For example, if you want to compare the ``$endDate`` property of some object
with regard to the ``$startDate`` property of the same object, use
@@ -433,10 +425,6 @@ notInRangeMessage
**type**: ``string`` **default**: ``This value should be between {{ min }} and {{ max }}.``
-.. versionadded:: 4.4
-
- The ``notInRangeMessage`` option was introduced in Symfony 4.4.
-
The message that will be shown if the underlying value is less than the
`min`_ option or greater than the `max`_ option.
diff --git a/reference/constraints/Sequentially.rst b/reference/constraints/Sequentially.rst
new file mode 100644
index 00000000000..a8e7c6be298
--- /dev/null
+++ b/reference/constraints/Sequentially.rst
@@ -0,0 +1,144 @@
+Sequentially
+============
+
+This constraint allows you to apply a set of rules that should be validated
+step-by-step, allowing to interrupt the validation once the first violation is raised.
+
+As an alternative in situations ``Sequentially`` cannot solve, you may consider
+using :doc:`GroupSequence` which allows more control.
+
+.. versionadded:: 5.1
+
+ The ``Sequentially`` constraint was introduced in Symfony 5.1.
+
+========== ===================================================================
+Applies to :ref:`property or method `
+Options - `constraints`_
+ - `groups`_
+ - `payload`_
+Class :class:`Symfony\\Component\\Validator\\Constraints\\Sequentially`
+Validator :class:`Symfony\\Component\\Validator\\Constraints\\SequentiallyValidator`
+========== ===================================================================
+
+Basic Usage
+-----------
+
+Suppose that you have a ``Place`` object with an ``$address`` property which
+must match the following requirements:
+
+* it's a non-blank string
+* of at least 10 chars long
+* with a specific format
+* and geolocalizable using an external service
+
+In such situations, you may encounter three issues:
+
+* the ``Length`` or ``Regex`` constraints may fail hard with a :class:`Symfony\\Component\\Validator\\Exception\\UnexpectedValueException`
+ exception if the actual value is not a string, as enforced by ``Type``.
+* you may end with multiple error messages for the same property
+* you may perform a useless and heavy external call to geolocalize the address,
+ while the format isn't valid.
+
+You can validate each of these constraints sequentially to solve these issues:
+
+.. configuration-block::
+
+ .. code-block:: php-annotations
+
+ // src/Localization/Place.php
+ namespace App\Localization;
+
+ use App\Validator\Constraints as AcmeAssert;
+ use Symfony\Component\Validator\Constraints as Assert;
+
+ class Place
+ {
+ /**
+ * @var string
+ *
+ * @Assert\Sequentially({
+ * @Assert\NotNull(),
+ * @Assert\Type("string"),
+ * @Assert\Length(min=10),
+ * @Assert\Regex(Place::ADDRESS_REGEX),
+ * @AcmeAssert\Geolocalizable(),
+ * })
+ */
+ public $address;
+ }
+
+ .. code-block:: yaml
+
+ # config/validator/validation.yaml
+ App\Localization\Place:
+ properties:
+ address:
+ - Sequentially:
+ - NotNull: ~
+ - Type: string
+ - Length: { min: 10 }
+ - Regex: !php/const App\Localization\Place::ADDRESS_REGEX
+ - App\Validator\Constraints\Geolocalizable: ~
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+ string
+
+
10
+
+
+
/address-regex/
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ // src/Localization/Place.php
+ namespace App\Localization;
+
+ use App\Validator\Constraints as AcmeAssert;
+ use Symfony\Component\Validator\Constraints as Assert;
+ use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+ class Place
+ {
+ public static function loadValidatorMetadata(ClassMetadata $metadata)
+ {
+ $metadata->addPropertyConstraint('address', new Assert\Sequentially([
+ new Assert\NotNull(),
+ new Assert\Type("string"),
+ new Assert\Length(['min' => 10]),
+ new Assert\Regex(self::ADDRESS_REGEX),
+ new AcmeAssert\Geolocalizable(),
+ ]));
+ }
+ }
+
+Options
+-------
+
+``constraints``
+~~~~~~~~~~~~~~~
+
+**type**: ``array`` [:ref:`default option `]
+
+This required option is the array of validation constraints that you want
+to apply sequentially.
+
+.. include:: /reference/constraints/_groups-option.rst.inc
+
+.. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/Timezone.rst b/reference/constraints/Timezone.rst
index c5f27e1cbfb..045c258bda4 100644
--- a/reference/constraints/Timezone.rst
+++ b/reference/constraints/Timezone.rst
@@ -1,10 +1,6 @@
Timezone
========
-.. versionadded:: 4.3
-
- The ``Timezone`` constraint was introduced in Symfony 4.3.
-
Validates that a value is a valid timezone identifier (e.g. ``Europe/Paris``).
========== ======================================================================
diff --git a/reference/constraints/Type.rst b/reference/constraints/Type.rst
index 8aa0edd1ba2..209520c41c7 100644
--- a/reference/constraints/Type.rst
+++ b/reference/constraints/Type.rst
@@ -143,11 +143,6 @@ This will check if ``id`` is an instance of ``Ramsey\Uuid\UuidInterface``,
}
}
-.. versionadded:: 4.4
-
- The feature to define multiple types in the ``type`` option was introduced
- in Symfony 4.4.
-
Options
-------
@@ -178,11 +173,6 @@ type
**type**: ``string`` or ``array`` [:ref:`default option `]
-.. versionadded:: 4.4
-
- The feature to define multiple types in the ``type`` option was introduced
- in Symfony 4.4.
-
This required option defines the type or collection of types allowed for the
given value. Each type is either the FQCN (fully qualified class name) of some
PHP class/interface or a valid PHP datatype (checked by PHP's ``is_()`` functions):
diff --git a/reference/constraints/Url.rst b/reference/constraints/Url.rst
index 4c9885d0147..fdc58880797 100644
--- a/reference/constraints/Url.rst
+++ b/reference/constraints/Url.rst
@@ -5,9 +5,7 @@ Validates that a value is a valid URL string.
========== ===================================================================
Applies to :ref:`property or method `
-Options - `checkDNS`_
- - `dnsMessage`_
- - `groups`_
+Options - `groups`_
- `message`_
- `normalizer`_
- `payload`_
@@ -76,170 +74,15 @@ Basic Usage
}
}
+This constraint doesn't check that the host of the given URL really exists,
+because the information of the DNS records is not reliable. Use the
+:phpfunction:`checkdnsrr` PHP function if you still want to check that.
+
.. include:: /reference/constraints/_empty-values-are-valid.rst.inc
Options
-------
-checkDNS
-~~~~~~~~
-
-**type**: ``boolean`` **default**: ``false``
-
-.. deprecated:: 4.1
-
- This option was deprecated in Symfony 4.1 and will be removed in Symfony 5.0,
- because checking the DNS records is not reliable enough to validate the
- existence of the host. Use the :phpfunction:`checkdnsrr` PHP function if you
- still want to use this kind of validation.
-
-By default, this constraint just validates the syntax of the given URL. If you
-also need to check whether the associated host exists, set the ``checkDNS``
-option to the value of any of the ``CHECK_DNS_TYPE_*`` constants in the
-:class:`Symfony\\Component\\Validator\\Constraints\\Url` class:
-
-.. configuration-block::
-
- .. code-block:: php-annotations
-
- // src/Entity/Author.php
- namespace App\Entity;
-
- use Symfony\Component\Validator\Constraints as Assert;
-
- class Author
- {
- /**
- * @Assert\Url(
- * checkDNS = "ANY"
- * )
- */
- protected $bioUrl;
- }
-
- .. code-block:: yaml
-
- # config/validator/validation.yaml
- App\Entity\Author:
- properties:
- bioUrl:
- - Url: { checkDNS: 'ANY' }
-
- .. code-block:: xml
-
-
-
-
-
-
-
-
-
ANY
-
-
-
-
-
- .. 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)
- {
- $metadata->addPropertyConstraint('bioUrl', new Assert\Url([
- 'checkDNS' => Assert\Url::CHECK_DNS_TYPE_ANY,
- ]));
- }
- }
-
-This option uses the :phpfunction:`checkdnsrr` PHP function to check the validity
-of the DNS record corresponding to the host associated with the given URL.
-
-dnsMessage
-~~~~~~~~~~
-
-**type**: ``string`` **default**: ``The host could not be resolved.``
-
-.. deprecated:: 4.1
-
- This option was deprecated in Symfony 4.1 and will be removed in Symfony 5.0,
- because checking the DNS records is not reliable enough to validate the
- existence of the host. Use the :phpfunction:`checkdnsrr` PHP function if you
- still want to use this kind of validation.
-
-This message is shown when the ``checkDNS`` option is set to ``true`` and the
-DNS check failed.
-
-.. configuration-block::
-
- .. code-block:: php-annotations
-
- // src/Entity/Author.php
- namespace App\Entity;
-
- use Symfony\Component\Validator\Constraints as Assert;
-
- class Author
- {
- /**
- * @Assert\Url(
- * dnsMessage = "The host '{{ value }}' could not be resolved."
- * )
- */
- protected $bioUrl;
- }
-
- .. code-block:: yaml
-
- # config/validator/validation.yaml
- App\Entity\Author:
- properties:
- bioUrl:
- - Url: { dnsMessage: 'The host "{{ value }}" could not be resolved.' }
-
- .. code-block:: xml
-
-
-
-
-
-
-
-
-
The host "{{ value }}" could not be resolved.
-
-
-
-
-
- .. 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)
- {
- $metadata->addPropertyConstraint('bioUrl', new Assert\Url([
- 'dnsMessage' => 'The host "{{ value }}" could not be resolved.',
- ]));
- }
- }
-
.. include:: /reference/constraints/_groups-option.rst.inc
message
diff --git a/reference/constraints/_comparison-propertypath-option.rst.inc b/reference/constraints/_comparison-propertypath-option.rst.inc
index 0491d7dea1f..35f0da4d189 100644
--- a/reference/constraints/_comparison-propertypath-option.rst.inc
+++ b/reference/constraints/_comparison-propertypath-option.rst.inc
@@ -15,7 +15,3 @@ with regard to the ``$startDate`` property of the same object, use
``{{ compared_value_path }}`` placeholder. Although it's not intended to
include it in the error messages displayed to end users, it's useful when
using APIs for doing any mapping logic on client-side.
-
- .. versionadded:: 4.4
-
- The ``{{ compared_value_path }}`` placeholder was introduced in Symfony 4.4.
diff --git a/reference/constraints/map.rst.inc b/reference/constraints/map.rst.inc
index 337798c51da..2d16e7e34ee 100644
--- a/reference/constraints/map.rst.inc
+++ b/reference/constraints/map.rst.inc
@@ -16,9 +16,11 @@ String Constraints
~~~~~~~~~~~~~~~~~~
* :doc:`Email `
+* :doc:`ExpressionLanguageSyntax `
* :doc:`Length `
* :doc:`Url `
* :doc:`Regex `
+* :doc:`Hostname `
* :doc:`Ip `
* :doc:`Json`
* :doc:`Uuid`
@@ -83,6 +85,9 @@ Financial and other Number Constraints
Other Constraints
~~~~~~~~~~~~~~~~~
+* :doc:`AtLeastOneOf `
+* :doc:`Sequentially `
+* :doc:`Compound `
* :doc:`Callback `
* :doc:`Expression `
* :doc:`All `
diff --git a/reference/dic_tags.rst b/reference/dic_tags.rst
index 7bb0aca674e..f7f43dca376 100644
--- a/reference/dic_tags.rst
+++ b/reference/dic_tags.rst
@@ -14,6 +14,8 @@ Tag Name Usage
`auto_alias`_ Define aliases based on the value of container parameters
`console.command`_ Add a command
`container.hot_path`_ Add to list of always needed services
+`container.no_preload`_ Remove a class from the list of classes preloaded by PHP
+`container.preload`_ Add some class to the list of classes preloaded by PHP
`controller.argument_value_resolver`_ Register a value resolver for controller arguments such as ``Request``
`data_collector`_ Create a class that collects custom data for the profiler
`doctrine.event_listener`_ Add a Doctrine event listener
@@ -38,7 +40,6 @@ Tag Name Usage
`serializer.encoder`_ Register a new encoder in the ``serializer`` service
`serializer.normalizer`_ Register a new normalizer in the ``serializer`` service
`swiftmailer.default.plugin`_ Register a custom SwiftMailer Plugin
-`templating.helper`_ Make your service available in PHP templates
`translation.loader`_ Register a custom service that loads translations
`translation.extractor`_ Register a custom service that extracts translation messages from a file
`translation.dumper`_ Register a custom service that dumps translation messages
@@ -181,10 +182,12 @@ wrapping their names with ``%`` characters).
sense most of the times to prevent accessing those services directly instead
of using the generic service alias.
-.. note::
+.. versionadded:: 5.1
- You need to manually add the ``Symfony\Component\DependencyInjection\Compiler\AutoAliasServicePass``
- compiler pass to the container for this feature to work.
+ In Symfony versions prior to 5.1, you needed to manually add the
+ ``Symfony\Component\DependencyInjection\Compiler\AutoAliasServicePass``
+ compiler pass to the container for this feature to work. This compiler pass
+ is now added automatically.
console.command
---------------
@@ -211,6 +214,113 @@ for services and their class hierarchy. The result is as significant performance
Use this tag with great caution, you have to be sure that the tagged service is always used.
+.. _dic-tags-container-nopreload:
+
+container.no_preload
+--------------------
+
+**Purpose**: Remove a class from the list of classes preloaded by PHP
+
+.. versionadded:: 5.1
+
+ The ``container.no_preload`` tag was introduced in Symfony 5.1.
+
+Add this tag to a service and its class won't be preloaded when using
+`PHP class preloading`_:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ services:
+ App\SomeNamespace\SomeService:
+ tags: ['container.no_preload']
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ use App\SomeNamespace\SomeService;
+
+ $container
+ ->register(SomeService::class)
+ ->addTag('container.no_preload')
+ ;
+
+If you add some service tagged with ``container.no_preload`` as an argument of
+another service, the ``container.no_preload`` tag is applied automatically to
+that service too.
+
+.. _dic-tags-container-preload:
+
+container.preload
+-----------------
+
+**Purpose**: Add some class to the list of classes preloaded by PHP
+
+.. versionadded:: 5.1
+
+ The ``container.preload`` tag was introduced in Symfony 5.1.
+
+When using `PHP class preloading`_, this tag allows you to define which PHP
+classes should be preloaded. This can improve performance by making some of the
+classes used by your service always available for all requests (until the server
+is restarted):
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ services:
+ App\SomeNamespace\SomeService:
+ tags:
+ - { name: 'container.preload', class: 'App\SomeClass' }
+ - { name: 'container.preload', class: 'App\Some\OtherClass' }
+ # ...
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ use App\Some\OtherClass;
+ use App\SomeClass;
+ use App\SomeNamespace\SomeService;
+
+ $container
+ ->register(SomeService::class)
+ ->addTag('container.preload', ['class' => SomeClass::class)
+ ->addTag('container.preload', ['class' => OtherClass::class)
+ // ...
+ ;
+
controller.argument_value_resolver
----------------------------------
@@ -362,6 +472,7 @@ the :class:`Symfony\\Component\\HttpKernel\\CacheWarmer\\CacheWarmerInterface` i
// src/Cache/MyCustomWarmer.php
namespace App\Cache;
+ use App\Foo\Bar;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
class MyCustomWarmer implements CacheWarmerInterface
@@ -369,6 +480,17 @@ the :class:`Symfony\\Component\\HttpKernel\\CacheWarmer\\CacheWarmerInterface` i
public function warmUp($cacheDirectory)
{
// ... do some sort of operations to "warm" your cache
+
+ $filesAndClassesToPreload = [];
+ $filesAndClassesToPreload[] = Bar::class;
+
+ foreach (scandir($someCacheDir) as $file) {
+ if (!is_dir($file = $someCacheDir.'/'.$file)) {
+ $filesAndClassesToPreload[] = $file;
+ }
+ }
+
+ return $filesAndClassesToPreload;
}
public function isOptional()
@@ -377,6 +499,16 @@ the :class:`Symfony\\Component\\HttpKernel\\CacheWarmer\\CacheWarmerInterface` i
}
}
+The ``warmUp()`` method must return an array with the files and classes to
+preload. Files must be absolute paths and classes must be fully-qualified class
+names. The only restriction is that files must be stored in the cache directory.
+If you don't need to preload anything, return an empty array
+
+.. deprecated:: 5.1
+
+ Not returning an array from the ``warmUp()`` method with the files to
+ preload is deprecated since Symfony 5.1.
+
The ``isOptional()`` method should return true if it's possible to use the
application without calling this cache warmer. In Symfony, optional warmers
are always executed by default (you can change this by using the
@@ -508,10 +640,6 @@ This tag is used to register your own :ref:`MIME type guessers `
don't fit your needs.
-.. versionadded:: 4.3
-
- The ``mime.mime_type_guesser`` tag was introduced in Symfony 4.3.
-
.. _dic_tags-monolog:
monolog.logger
@@ -834,53 +962,6 @@ For more information on plugins, see `SwiftMailer's Plugin Documentation`_.
Several SwiftMailer plugins are core to Symfony and can be activated via
different configuration. For details, see :doc:`/reference/configuration/swiftmailer`.
-templating.helper
------------------
-
-**Purpose**: Make your service available in PHP templates
-
-.. deprecated:: 4.3
-
- The ``templating.helper`` tag is deprecated since version 4.3 and will be
- removed in 5.0; use Twig instead.
-
-To enable a custom template helper, add it as a regular service in one
-of your configuration, tag it with ``templating.helper`` and define an
-``alias`` attribute (the helper will be accessible via this alias in the
-templates):
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- services:
- App\Templating\AppHelper:
- tags:
- - { name: templating.helper, alias: alias_name }
-
- .. code-block:: xml
-
-
-
-
-
-
-
-
-
-
-
- .. code-block:: php
-
- use App\Templating\AppHelper;
-
- $container->register(AppHelper::class)
- ->addTag('templating.helper', ['alias' => 'alias_name'])
- ;
-
.. _dic-tags-translation-loader:
translation.loader
@@ -1264,3 +1345,4 @@ Bridge.
.. _`Twig's documentation`: https://twig.symfony.com/doc/2.x/advanced.html#creating-an-extension
.. _`SwiftMailer's Plugin Documentation`: https://swiftmailer.symfony.com/docs/plugins.html
.. _`Twig Loader`: https://twig.symfony.com/doc/2.x/api.html#loaders
+.. _`PHP class preloading`: https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.preload
diff --git a/reference/forms/types/button.rst b/reference/forms/types/button.rst
index 20ae46ca6d4..655d515215b 100644
--- a/reference/forms/types/button.rst
+++ b/reference/forms/types/button.rst
@@ -13,6 +13,7 @@ A simple, non-responsive button.
| options | - `attr_translation_parameters`_ |
| | - `disabled`_ |
| | - `label`_ |
+| | - `label_html`_ |
| | - `label_translation_parameters`_ |
| | - `row_attr`_ |
| | - `translation_domain`_ |
@@ -53,6 +54,8 @@ as a key. This can be useful when you need to set a custom class for the button:
.. include:: /reference/forms/types/options/button_label.rst.inc
+.. include:: /reference/forms/types/options/label_html.rst.inc
+
.. include:: /reference/forms/types/options/button_translation_domain.rst.inc
label_translation_parameters
@@ -60,10 +63,6 @@ label_translation_parameters
**type**: ``array`` **default**: ``[]``
-.. versionadded:: 4.3
-
- The ``label_translation_parameters`` option was introduced in Symfony 4.3.
-
The content of the `label`_ option is translated before displaying it, so it
can contain :ref:`translation placeholders `.
This option defines the values used to replace those placeholders.
diff --git a/reference/forms/types/choice.rst b/reference/forms/types/choice.rst
index d90173eb2e6..fb1df969b9d 100644
--- a/reference/forms/types/choice.rst
+++ b/reference/forms/types/choice.rst
@@ -14,6 +14,7 @@ To use this field, you must specify *either* ``choices`` or ``choice_loader`` op
+-------------+------------------------------------------------------------------------------+
| Options | - `choices`_ |
| | - `choice_attr`_ |
+| | - `choice_filter`_ |
| | - `choice_label`_ |
| | - `choice_loader`_ |
| | - `choice_name`_ |
@@ -181,6 +182,11 @@ To get fancier, use the `group_by`_ option instead.
Field Options
-------------
+.. versionadded:: 5.1
+
+ The :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList` class was
+ introduced in Symfony 5.1, to help configuring choices options.
+
choices
~~~~~~~
@@ -207,35 +213,15 @@ correct types will be assigned to the model.
.. include:: /reference/forms/types/options/choice_attr.rst.inc
+.. include:: /reference/forms/types/options/choice_filter.rst.inc
+
.. _reference-form-choice-label:
.. include:: /reference/forms/types/options/choice_label.rst.inc
-choice_loader
-~~~~~~~~~~~~~
-
-**type**: :class:`Symfony\\Component\\Form\\ChoiceList\\Loader\\ChoiceLoaderInterface`
-
-The ``choice_loader`` can be used to only partially load the choices in cases where
-a fully-loaded list is not necessary. This is only needed in advanced cases and
-would replace the ``choices`` option.
-
-You can use an instance of :class:`Symfony\\Component\\Form\\ChoiceList\\Loader\\CallbackChoiceLoader`
-if you want to take advantage of lazy loading::
-
- use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader;
- use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
- // ...
-
- $builder->add('constants', ChoiceType::class, [
- 'choice_loader' => new CallbackChoiceLoader(function() {
- return StaticClass::getConstants();
- }),
- ]);
+.. _reference-form-choice-loader:
-This will cause the call of ``StaticClass::getConstants()`` to not happen if the
-request is redirected and if there is no pre set or submitted data. Otherwise
-the choice options would need to be resolved thus triggering the callback.
+.. include:: /reference/forms/types/options/choice_loader.rst.inc
.. include:: /reference/forms/types/options/choice_name.rst.inc
diff --git a/reference/forms/types/color.rst b/reference/forms/types/color.rst
index f6e4ec5ba58..a290b31e673 100644
--- a/reference/forms/types/color.rst
+++ b/reference/forms/types/color.rst
@@ -17,6 +17,8 @@ element.
+-------------+---------------------------------------------------------------------+
| Rendered as | ``input`` ``color`` field (a text box) |
+-------------+---------------------------------------------------------------------+
+| Options | - `html5`_ |
++-------------+---------------------------------------------------------------------+
| Inherited | - `attr`_ |
| options | - `data`_ |
| | - `disabled`_ |
@@ -41,6 +43,22 @@ element.
.. include:: /reference/forms/types/options/_debug_form.rst.inc
+Field Options
+-------------
+
+html5
+~~~~~
+
+**type**: ``bool`` **default**: ``false``
+
+.. versionadded:: 5.1
+
+ This option was introduced in Symfony 5.1.
+
+When this option is set to ``true``, the form type checks that its value matches
+the `HTML5 color format`_ (``/^#[0-9a-f]{6}$/i``). If it doesn't match it,
+you'll see the following error message: *"This value is not a valid HTML5 color"*.
+
Inherited Options
-----------------
@@ -83,3 +101,5 @@ The default value is ``''`` (the empty string).
.. include:: /reference/forms/types/options/row_attr.rst.inc
.. include:: /reference/forms/types/options/trim.rst.inc
+
+.. _`HTML5 color format`: https://www.w3.org/TR/html52/sec-forms.html#color-state-typecolor
diff --git a/reference/forms/types/country.rst b/reference/forms/types/country.rst
index dee6827a0ca..bbda2b3ec46 100644
--- a/reference/forms/types/country.rst
+++ b/reference/forms/types/country.rst
@@ -68,10 +68,6 @@ alpha3
**type**: ``boolean`` **default**: ``false``
-.. versionadded:: 4.4
-
- The ``alpha3`` option was introduced in Symfony 4.4.
-
If this option is ``true``, the choice values use the `ISO 3166-1 alpha-3`_
three-letter codes (e.g. New Zealand = ``NZL``) instead of the default
`ISO 3166-1 alpha-2`_ two-letter codes (e.g. New Zealand = ``NZ``).
diff --git a/reference/forms/types/date.rst b/reference/forms/types/date.rst
index c69f7fd05f0..ea96cf3d937 100644
--- a/reference/forms/types/date.rst
+++ b/reference/forms/types/date.rst
@@ -173,11 +173,6 @@ values for the year, month and day fields::
.. include:: /reference/forms/types/options/date_format.rst.inc
-.. deprecated:: 4.3
-
- Using the ``format`` option when the ``html5`` option is enabled is deprecated
- since Symfony 4.3.
-
.. include:: /reference/forms/types/options/html5.rst.inc
.. _form-reference-date-input:
diff --git a/reference/forms/types/datetime.rst b/reference/forms/types/datetime.rst
index 6adc3e733eb..72af8847075 100644
--- a/reference/forms/types/datetime.rst
+++ b/reference/forms/types/datetime.rst
@@ -76,11 +76,6 @@ Defines the ``format`` option that will be passed down to the date field.
See the :ref:`DateType's format option `
for more details.
-.. deprecated:: 4.3
-
- Using the ``date_format`` option when the form is rendered as an HTML 5
- datetime input is deprecated since Symfony 4.3.
-
date_label
~~~~~~~~~~
@@ -100,11 +95,6 @@ date_widget
.. include:: /reference/forms/types/options/date_widget_description.rst.inc
-.. deprecated:: 4.3
-
- Using the ``date_widget`` option when the ``widget`` option is set to
- ``single_text`` is deprecated since Symfony 4.3.
-
.. include:: /reference/forms/types/options/days.rst.inc
placeholder
@@ -146,11 +136,6 @@ used by the HTML5 ``datetime-local`` field. Keeping the default value will
cause the field to be rendered as an ``input`` field with ``type="datetime-local"``.
For more information on valid formats, see `Date/Time Format Syntax`_.
-.. deprecated:: 4.3
-
- Using the ``format`` option when the ``html5`` option is enabled is deprecated
- since Symfony 4.3.
-
.. include:: /reference/forms/types/options/hours.rst.inc
.. include:: /reference/forms/types/options/html5.rst.inc
@@ -210,11 +195,6 @@ time_widget
Defines the ``widget`` option for the :doc:`TimeType `.
-.. deprecated:: 4.3
-
- Using the ``time_widget`` option when the ``widget`` option is set to
- ``single_text`` is deprecated since Symfony 4.3.
-
.. include:: /reference/forms/types/options/view_timezone.rst.inc
widget
diff --git a/reference/forms/types/form.rst b/reference/forms/types/form.rst
index 4099436430b..8a0c219f410 100644
--- a/reference/forms/types/form.rst
+++ b/reference/forms/types/form.rst
@@ -42,6 +42,7 @@ on all types for which ``FormType`` is the parent.
| | - `block_prefix`_ |
| | - `disabled`_ |
| | - `label`_ |
+| | - `label_html`_ |
| | - `row_attr`_ |
| | - `translation_domain`_ |
| | - `label_translation_parameters`_ |
@@ -172,6 +173,8 @@ of the form type tree (i.e. it cannot be used as a form type on its own).
.. include:: /reference/forms/types/options/label.rst.inc
+.. include:: /reference/forms/types/options/label_html.rst.inc
+
.. include:: /reference/forms/types/options/row_attr.rst.inc
.. include:: /reference/forms/types/options/translation_domain.rst.inc
diff --git a/reference/forms/types/integer.rst b/reference/forms/types/integer.rst
index d228f4f8145..fa5660158bc 100644
--- a/reference/forms/types/integer.rst
+++ b/reference/forms/types/integer.rst
@@ -20,7 +20,7 @@ integers. By default, all non-integer values (e.g. 6.78) will round down
| | - `rounding_mode`_ |
+-------------+-----------------------------------------------------------------------+
| Overridden | - `compound`_ |
-| options | - `scale`_ |
+| options | |
+-------------+-----------------------------------------------------------------------+
| Inherited | - `attr`_ |
| options | - `data`_ |
@@ -86,21 +86,6 @@ Overridden Options
.. include:: /reference/forms/types/options/compound_type.rst.inc
-``scale``
-~~~~~~~~~
-
-**type**: ``integer`` **default**: ``0``
-
-.. deprecated:: 4.2
-
- The ``scale`` option is deprecated since Symfony 4.2 and will be removed
- in 5.0.
-
-This specifies how many decimals will be allowed until the field rounds the
-submitted value (via ``rounding_mode``). This option inherits from
-:doc:`number ` type and is overridden to ``0`` for
-``IntegerType``.
-
Inherited Options
-----------------
diff --git a/reference/forms/types/language.rst b/reference/forms/types/language.rst
index bba93983ca4..bf2c99789f8 100644
--- a/reference/forms/types/language.rst
+++ b/reference/forms/types/language.rst
@@ -24,6 +24,7 @@ manually, but then you should just use the ``ChoiceType`` directly.
| Rendered as | can be various tags (see :ref:`forms-reference-choice-tags`) |
+-------------+------------------------------------------------------------------------+
| Options | - `alpha3`_ |
+| | - `choice_self_translation`_ |
| | - `choice_translation_locale`_ |
+-------------+------------------------------------------------------------------------+
| Overridden | - `choices`_ |
@@ -70,14 +71,29 @@ alpha3
**type**: ``boolean`` **default**: ``false``
-.. versionadded:: 4.4
-
- The ``alpha3`` option was introduced in Symfony 4.4.
-
If this option is ``true``, the choice values use the `ISO 639-2 alpha-3`_
three-letter codes (e.g. French = ``fra``) instead of the default
`ISO 639-1 alpha-2`_ two-letter codes (e.g. French = ``fr``).
+choice_self_translation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+**type**: ``boolean`` **default**: ``false``
+
+.. versionadded:: 5.1
+
+ The ``choice_self_translation`` option was introduced in Symfony 5.1.
+
+By default, language names are translated into the current locale of the
+application. For example, when browsing the application in English, you'll get
+an array like ``[..., 'cs' => 'Czech', ..., 'es' => 'Spanish', ..., 'zh' => 'Chinese']``
+and when browsing it in French, you'll get the following array:
+``[..., 'cs' => 'tchèque', ..., 'es' => 'espagnol', ..., 'zh' => 'chinois']``.
+
+If this option is ``true``, each language is translated into its own language,
+regardless of the current application locale:
+``[..., 'cs' => 'čeština', ..., 'es' => 'español', ..., 'zh' => '中文']``.
+
.. include:: /reference/forms/types/options/choice_translation_locale.rst.inc
Overridden Options
diff --git a/reference/forms/types/number.rst b/reference/forms/types/number.rst
index 6e9215c276a..599d0efa4cd 100644
--- a/reference/forms/types/number.rst
+++ b/reference/forms/types/number.rst
@@ -55,10 +55,6 @@ html5
**type**: ``boolean`` **default**: ``false``
-.. versionadded:: 4.3
-
- The ``html5`` option was introduced in Symfony 4.3.
-
If set to ``true``, the HTML input will be rendered as a native HTML5 ``type="number"``
form.
@@ -67,10 +63,6 @@ input
**type**: ``string`` **default**: ``number``
-.. versionadded:: 4.3
-
- The ``input`` option was introduced in Symfony 4.3.
-
The format of the input data - i.e. the format that the number is stored on
your underlying object. Valid values are ``number`` and ``string``. Setting
this option to ``string`` can be useful if the underlying data is a string
diff --git a/reference/forms/types/options/attr_translation_parameters.rst.inc b/reference/forms/types/options/attr_translation_parameters.rst.inc
index 98326ba4abe..71187cd75c5 100644
--- a/reference/forms/types/options/attr_translation_parameters.rst.inc
+++ b/reference/forms/types/options/attr_translation_parameters.rst.inc
@@ -3,10 +3,6 @@ attr_translation_parameters
**type**: ``array`` **default**: ``[]``
-.. versionadded:: 4.3
-
- The ``attr_translation_parameters`` option was introduced in Symfony 4.3.
-
The content of the ``title`` and ``placeholder`` values defined in the `attr`_
option is translated before displaying it, so it can contain
:ref:`translation placeholders `. This
diff --git a/reference/forms/types/options/block_prefix.rst.inc b/reference/forms/types/options/block_prefix.rst.inc
index f02feb0ce70..db012bc3c42 100644
--- a/reference/forms/types/options/block_prefix.rst.inc
+++ b/reference/forms/types/options/block_prefix.rst.inc
@@ -4,10 +4,6 @@ block_prefix
**type**: ``string`` or ``null`` **default**: ``null`` (see :ref:`Knowing which
block to customize `)
-.. versionadded:: 4.3
-
- The ``block_prefix`` option was introduced in Symfony 4.3.
-
Allows you to add a custom block prefix and override the block name
used to render the form type. Useful for example if you have multiple
instances of the same form and you need to personalize the rendering
diff --git a/reference/forms/types/options/choice_attr.rst.inc b/reference/forms/types/options/choice_attr.rst.inc
index ac149f3999d..1c9f5138d66 100644
--- a/reference/forms/types/options/choice_attr.rst.inc
+++ b/reference/forms/types/options/choice_attr.rst.inc
@@ -24,3 +24,20 @@ If an array, the keys of the ``choices`` array must be used as keys::
return ['class' => 'attending_'.strtolower($key)];
},
]);
+
+.. tip::
+
+ When defining a custom type, you should use the
+ :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList` class helper::
+
+ use App\Entity\Category;
+ use Symfony\Component\Form\ChoiceList\ChoiceList;
+
+ // ...
+ $builder->add('choices', ChoiceType::class, [
+ 'choice_label' => ChoiceList::attr($this, function (?Category $category) {
+ return $category ? ['data-uuid' => $category->getUuid()] : [];
+ }),
+ ]);
+
+ See the :ref:`"choice_loader" option documentation `.
diff --git a/reference/forms/types/options/choice_filter.rst.inc b/reference/forms/types/options/choice_filter.rst.inc
new file mode 100644
index 00000000000..d7563dc8a1c
--- /dev/null
+++ b/reference/forms/types/options/choice_filter.rst.inc
@@ -0,0 +1,82 @@
+``choice_filter``
+~~~~~~~~~~~~~~~~~
+
+**type**: ``callable``, ``string`` or :class:`Symfony\\Component\\PropertyAccess\\PropertyPath` **default**: ``null``
+
+.. versionadded:: 5.1
+
+ The ``choice_filter`` option has been introduced in Symfony 5.1.
+
+When using predefined choice types from Symfony core or vendor libraries (i.e.
+:doc:`CountryType `) this option lets you
+define a callable that takes each choice as the only argument and must return
+``true`` to keep it or ``false`` to discard it::
+
+ // src/Form/Type/AddressType.php
+ namespace App\Form\Type;
+
+ use Symfony\Component\Form\AbstractType;
+ use Symfony\Component\Form\Extension\Core\Type\CountryType;
+ use Symfony\Component\Form\FormBuilderInterface;
+ use Symfony\Component\OptionsResolver\OptionsResolver;
+
+ class AddressType extends AbstractType
+ {
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver
+ ->setDefaults([
+ // enable this type to accept a limited set of countries
+ 'allowed_countries' => null,
+ ])
+ ;
+ }
+
+ public function buildForm(FormBuilderInterface $builder, array $options)
+ {
+ $allowedCountries = $options['allowed_countries'];
+
+ $builder
+ // ...
+ ->add('country', CountryType::class, [
+ // if the AddressType "allowed_countries" option is passed,
+ // use it to create a filter
+ 'choice_filter' => $allowedCountries ? function ($countryCode) use ($allowedCountries) {
+ return in_array($countryCode, $allowedCountries, true);
+ } : null,
+
+ ])
+ ;
+ }
+
+The option can be a callable or a property path when choices are objects::
+
+ // ...
+ $builder
+ ->add('category', ChoiceType::class, [
+ // ...
+ 'choice_filter' => 'isSelectable',
+ ])
+ ;
+
+.. tip::
+
+ Considering this ``AddressType`` could be an entry of a ``CollectionType``
+ you should use the :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList`
+ class helper to enable caching::
+
+ // src/Form/Type/AddressType.php
+ // ...
+ use Symfony\Component\Form\ChoiceList\ChoiceList;
+
+ // ...
+ 'choice_filter' => $allowedCountries ? ChoiceList::filter(
+ // pass the type as first argument
+ $this,
+ function ($countryCode) use ($allowedCountries) {
+ return in_array($countryCode, $allowedCountries, true);
+ },
+ // pass the option that makes the filter "vary" to compute a unique hash
+ $allowedCountries
+ ) : null,
+ // ...
diff --git a/reference/forms/types/options/choice_label.rst.inc b/reference/forms/types/options/choice_label.rst.inc
index 53cd469b916..6cfac9323ae 100644
--- a/reference/forms/types/options/choice_label.rst.inc
+++ b/reference/forms/types/options/choice_label.rst.inc
@@ -53,3 +53,17 @@ If your choice values are objects, then ``choice_label`` can also be a
If set to ``false``, all the tag labels will be discarded for radio or checkbox
inputs. You can also return ``false`` from the callable to discard certain labels.
+
+.. tip::
+
+ When defining a custom type, you should use the
+ :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList` class helper::
+
+ use Symfony\Component\Form\ChoiceList\ChoiceList;
+
+ // ...
+ $builder->add('choices', ChoiceType::class, [
+ 'choice_label' => ChoiceList::label($this, 'displayName'),
+ ]);
+
+ See the :ref:`"choice_loader" option documentation `.
diff --git a/reference/forms/types/options/choice_loader.rst.inc b/reference/forms/types/options/choice_loader.rst.inc
new file mode 100644
index 00000000000..c44601ed3eb
--- /dev/null
+++ b/reference/forms/types/options/choice_loader.rst.inc
@@ -0,0 +1,75 @@
+choice_loader
+~~~~~~~~~~~~~
+
+**type**: :class:`Symfony\\Component\\Form\\ChoiceList\\Loader\\ChoiceLoaderInterface`
+
+The ``choice_loader`` option can be used instead of the ``choices`` option. It
+allows to create a list lazily or partially when fetching only the choices for a
+set of submitted values (i.e. querying a search engine like ``ElasticSearch``
+can be a heavy process).
+
+You can use an instance of :class:`Symfony\\Component\\Form\\ChoiceList\\Loader\\CallbackChoiceLoader`
+if you want to take advantage of lazy loading::
+
+ use App\StaticClass;
+ use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader;
+ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
+ // ...
+
+ $builder->add('loaded_choices', ChoiceType::class, [
+ 'choice_loader' => new CallbackChoiceLoader(function() {
+ return StaticClass::getConstants();
+ }),
+ ]);
+
+This will cause the call of ``StaticClass::getConstants()`` to not happen if the
+request is redirected and if there is no pre set or submitted data. Otherwise
+the choice options would need to be resolved thus triggering the callback.
+
+When you're defining a custom choice type that may be reused in many fields
+(like entries of a collection) or reused in multiple forms at once, you
+should use the :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList`
+static methods to wrap the loader and make the choice list cacheable for
+better performance::
+
+ use App\Form\ChoiceList\CustomChoiceLoader;
+ use App\StaticClass;
+ use Symfony\Component\Form\AbstractType;
+ use Symfony\Component\Form\ChoiceList\ChoiceList;
+ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
+ use Symfony\Component\OptionsResolver\Options;
+ use Symfony\Component\OptionsResolver\OptionsResolver;
+
+ class ConstantsType extends AbstractType
+ {
+ public static function getExtendedTypes(): iterable
+ {
+ return [ChoiceType::class];
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults([
+ // the example below will create a CallbackChoiceLoader from the callable
+ 'choice_loader' => ChoiceList::lazy($this, function() {
+ return StaticClass::getConstants();
+ }),
+
+ // you can pass your own loader as well, depending on other options
+ 'some_key' => null,
+ 'choice_loader' => function (Options $options) {
+ return ChoiceList::loader(
+ // pass the instance of the type or type extension which is
+ // currently configuring the choice list as first argument
+ $this,
+ // pass the other option to the loader
+ new CustomChoiceLoader($options['some_key']),
+ // ensure the type stores a loader per key
+ // by using the special third argument "$vary"
+ // an array containing anything that "changes" the loader
+ [$options['some_key']]
+ );
+ },
+ ]);
+ }
+ }
diff --git a/reference/forms/types/options/choice_name.rst.inc b/reference/forms/types/options/choice_name.rst.inc
index a01341b5418..4ec8abb6ffe 100644
--- a/reference/forms/types/options/choice_name.rst.inc
+++ b/reference/forms/types/options/choice_name.rst.inc
@@ -5,12 +5,26 @@
Controls the internal field name of the choice. You normally don't care about this,
but in some advanced cases, you might. For example, this "name" becomes the index
-of the choice views in the template and is used as part o the field name
+of the choice views in the template and is used as part of the field name
attribute.
This can be a callable or a property path. See `choice_label`_ for similar usage.
By default, the choice key or an incrementing integer may be used (starting at ``0``).
+.. tip::
+
+ When defining a custom type, you should use the
+ :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList` class helper::
+
+ use Symfony\Component\Form\ChoiceList\ChoiceList;
+
+ // ...
+ $builder->add('choices', ChoiceType::class, [
+ 'choice_name' => ChoiceList::fieldName($this, 'name'),
+ ]);
+
+ See the :ref:`"choice_loader" option documentation `.
+
.. caution::
The configured value must be a valid form name. Make sure to only return
diff --git a/reference/forms/types/options/choice_value.rst.inc b/reference/forms/types/options/choice_value.rst.inc
index a37a36cf299..13bc324cd2a 100644
--- a/reference/forms/types/options/choice_value.rst.inc
+++ b/reference/forms/types/options/choice_value.rst.inc
@@ -18,3 +18,17 @@ for each choice or ``null`` in a placeholder is used, which you need to handle::
'choice_value' => function (?MyOptionEntity $entity) {
return $entity ? $entity->getId() : '';
},
+
+.. tip::
+
+ When defining a custom type, you should use the
+ :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList` class helper::
+
+ use Symfony\Component\Form\ChoiceList\ChoiceList;
+
+ // ...
+ $builder->add('choices', ChoiceType::class, [
+ 'choice_value' => ChoiceList::value($this, 'uuid'),
+ ]);
+
+ See the :ref:`"choice_loader" option documentation `.
diff --git a/reference/forms/types/options/date_input_format_description.rst.inc b/reference/forms/types/options/date_input_format_description.rst.inc
index 4cd9b353e31..e411cd12d70 100644
--- a/reference/forms/types/options/date_input_format_description.rst.inc
+++ b/reference/forms/types/options/date_input_format_description.rst.inc
@@ -1,7 +1,3 @@
-.. versionadded:: 4.3
-
- The ``input_format`` option was introduced in Symfony 4.3.
-
If the ``input`` option is set to ``string``, this option specifies the format
of the date. This must be a valid `PHP date format`_.
diff --git a/reference/forms/types/options/extra_fields_message.rst.inc b/reference/forms/types/options/extra_fields_message.rst.inc
index ca54c91ec54..5c969f7afce 100644
--- a/reference/forms/types/options/extra_fields_message.rst.inc
+++ b/reference/forms/types/options/extra_fields_message.rst.inc
@@ -1,9 +1,17 @@
``extra_fields_message``
~~~~~~~~~~~~~~~~~~~~~~~~
+.. versionadded:: 5.1
+
+ Pluralization support was introduced in Symfony 5.1.
+
**type**: ``string`` **default**: ``This form should not contain extra fields.``
This is the validation error message that's used if the submitted form data
contains one or more fields that are not part of the form definition. The
placeholder ``{{ extra_fields }}`` can be used to display a comma separated
list of the submitted extra field names.
+
+This message can be pluralized, see
+:ref:`formatting pluralized messages ` for
+details.
diff --git a/reference/forms/types/options/group_by.rst.inc b/reference/forms/types/options/group_by.rst.inc
index b649793e9ff..ca747683662 100644
--- a/reference/forms/types/options/group_by.rst.inc
+++ b/reference/forms/types/options/group_by.rst.inc
@@ -40,3 +40,17 @@ a "Later" ``