From 291cded9c71731284f03ab10d9bcb7da0ca26420 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 1 Jun 2023 11:36:26 +0200
Subject: [PATCH 001/747] Upgrade the minimum PHP version requirement for
 Symfony 7.0

---
 setup.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/setup.rst b/setup.rst
index 7bb5a8010a2..b75335c9dd6 100644
--- a/setup.rst
+++ b/setup.rst
@@ -14,7 +14,7 @@ Technical Requirements
 
 Before creating your first Symfony application you must:
 
-* Install PHP 8.1 or higher and these PHP extensions (which are installed and
+* Install PHP 8.2 or higher and these PHP extensions (which are installed and
   enabled by default in most PHP 8 installations): `Ctype`_, `iconv`_,
   `PCRE`_, `Session`_, `SimpleXML`_, and `Tokenizer`_;
 * `Install Composer`_, which is used to install PHP packages.

From 68f135862f28f388b90ae9196380697f80e7ba08 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 5 Jun 2023 08:37:14 +0200
Subject: [PATCH 002/747] Update setup docs for Symfony 7.0

---
 setup.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/setup.rst b/setup.rst
index e8f3ee791a2..0ad060d8480 100644
--- a/setup.rst
+++ b/setup.rst
@@ -46,10 +46,10 @@ application:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ symfony new my_project_directory --version="6.4.*@dev" --webapp
+    $ symfony new my_project_directory --version="7.0.*@dev" --webapp
 
     # run this if you are building a microservice, console application or API
-    $ symfony new my_project_directory --version="6.4.*@dev"
+    $ symfony new my_project_directory --version="7.0.*@dev"
 
 The only difference between these two commands is the number of packages
 installed by default. The ``--webapp`` option installs all the packages that you
@@ -61,12 +61,12 @@ Symfony application using Composer:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ composer create-project symfony/skeleton:"6.4.*@dev" my_project_directory
+    $ composer create-project symfony/skeleton:"7.0.*@dev" my_project_directory
     $ cd my_project_directory
     $ composer require webapp
 
     # run this if you are building a microservice, console application or API
-    $ composer create-project symfony/skeleton:"6.4.*@dev" my_project_directory
+    $ composer create-project symfony/skeleton:"7.0.*@dev" my_project_directory
 
 No matter which command you run to create the Symfony application. All of them
 will create a new ``my_project_directory/`` directory, download some dependencies

From 2d674cf6abd9716fbfc71e3c00e6f54f56a1f78f Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Fri, 30 Jun 2023 14:04:31 +0200
Subject: [PATCH 003/747] [Console] Remove occurrences of `$defaultName` and
 `$defaultDescription`

---
 console.rst | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/console.rst b/console.rst
index 4038c16f83e..edac5545e9e 100644
--- a/console.rst
+++ b/console.rst
@@ -146,13 +146,12 @@ You can optionally define a description, help message and the
     // ...
     class CreateUserCommand extends Command
     {
-        // the command description shown when running "php bin/console list"
-        protected static $defaultDescription = 'Creates a new user.';
-
         // ...
         protected function configure(): void
         {
             $this
+                // the command description shown when running "php bin/console list"
+                ->setDescription('Creates a new user.')
                 // the command help shown when running the command with the "--help" option
                 ->setHelp('This command allows you to create a user...')
             ;
@@ -161,15 +160,16 @@ You can optionally define a description, help message and the
 
 .. tip::
 
-    Defining the ``$defaultDescription`` static property instead of using the
-    ``setDescription()`` method allows to get the command description without
+    Using the ``#[AsCommand]`` attribute to define a description instead of
+    using the ``setDescription()`` method allows to get the command description without
     instantiating its class. This makes the ``php bin/console list`` command run
     much faster.
 
     If you want to always run the ``list`` command fast, add the ``--short`` option
     to it (``php bin/console list --short``). This will avoid instantiating command
     classes, but it won't show any description for commands that use the
-    ``setDescription()`` method instead of the static property.
+    ``setDescription()`` method instead of the attribute to define the command
+    description.
 
 The ``configure()`` method is called automatically at the end of the command
 constructor. If your command defines its own constructor, set the properties
@@ -216,8 +216,6 @@ You can register the command by adding the ``AsCommand`` attribute to it::
     use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Command\Command;
 
-    // the "name" and "description" arguments of AsCommand replace the
-    // static $defaultName and $defaultDescription properties
     #[AsCommand(
         name: 'app:create-user',
         description: 'Creates a new user.',

From 1a68fb07e9ecb73b108dad68183f04aaf2aae2ed Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Fri, 30 Jun 2023 18:05:09 +0200
Subject: [PATCH 004/747] [HttpKernel] Remove `ContainerAwareInterface`
 occurrence

---
 components/http_kernel.rst | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/components/http_kernel.rst b/components/http_kernel.rst
index 90e0194f529..937028c28a4 100644
--- a/components/http_kernel.rst
+++ b/components/http_kernel.rst
@@ -258,18 +258,6 @@ on the request's information.
     b) A new instance of your controller class is instantiated with no
        constructor arguments.
 
-    c) If the controller implements :class:`Symfony\\Component\\DependencyInjection\\ContainerAwareInterface`,
-       ``setContainer()`` is called on the controller object and the container
-       is passed to it. This step is also specific to the  :class:`Symfony\\Bundle\\FrameworkBundle\\Controller\\ControllerResolver`
-       sub-class used by the Symfony Framework.
-
-.. deprecated:: 6.4
-
-    :class:`Symfony\\Component\\DependencyInjection\\ContainerAwareInterface` and
-    :class:`Symfony\\Component\\DependencyInjection\\ContainerAwareTrait` are
-    deprecated since Symfony 6.4. Dependency injection should be used instead to
-    access the service container.
-
 .. _component-http-kernel-kernel-controller:
 
 3) The ``kernel.controller`` Event

From e46a7a0a28d9740ed8590d4bc67522c644f8c3b7 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Fri, 30 Jun 2023 19:48:14 +0200
Subject: [PATCH 005/747] Remove deprecated directive

---
 reference/forms/types/options/model_timezone.rst.inc | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/reference/forms/types/options/model_timezone.rst.inc b/reference/forms/types/options/model_timezone.rst.inc
index 44050e89219..0ef0efe1b56 100644
--- a/reference/forms/types/options/model_timezone.rst.inc
+++ b/reference/forms/types/options/model_timezone.rst.inc
@@ -6,10 +6,4 @@
 Timezone that the input data is stored in. This must be one of the
 `PHP supported timezones`_.
 
-.. deprecated:: 6.4
-
-    Starting from Symfony 6.4, it's deprecated to pass ``DateTime`` or ``DateTimeImmutable``
-    values to this form field with a different timezone than the one configured with
-    the ``model_timezone`` option.
-
 .. _`PHP supported timezones`: https://www.php.net/manual/en/timezones.php

From ba5059e10fa24b62501e79f0fd9f2e81ba321fb2 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 4 Jul 2023 10:13:58 +0200
Subject: [PATCH 006/747] [ExpressionLanguage] `in` and `not in` operators are
 using strict comparison

---
 reference/formats/expression_language.rst | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/reference/formats/expression_language.rst b/reference/formats/expression_language.rst
index 18811c0ca44..ebb7574922c 100644
--- a/reference/formats/expression_language.rst
+++ b/reference/formats/expression_language.rst
@@ -352,12 +352,9 @@ For example::
 
 The ``$inGroup`` would evaluate to ``true``.
 
-.. deprecated:: 6.3
+.. note::
 
-    In Symfony versions previous to 6.3, ``in`` and ``not in`` operators
-    were using loose comparison. Using these operators with variables of
-    different types is now deprecated, and these operators will be using
-    strict comparison from Symfony 7.0.
+    The ``in`` and ``not in`` operators are using strict comparison.
 
 Numeric Operators
 ~~~~~~~~~~~~~~~~~

From b44d4c41f5cb0247639f745ec983c60b1328b531 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 4 Jul 2023 14:12:02 +0200
Subject: [PATCH 007/747] [Validator] Remove deprecated
 `ExpressionLanguageSyntax` constraint

---
 .../constraints/ExpressionLanguageSyntax.rst  | 127 ------------------
 reference/constraints/ExpressionSyntax.rst    |   6 -
 2 files changed, 133 deletions(-)
 delete mode 100644 reference/constraints/ExpressionLanguageSyntax.rst

diff --git a/reference/constraints/ExpressionLanguageSyntax.rst b/reference/constraints/ExpressionLanguageSyntax.rst
deleted file mode 100644
index f10956c4046..00000000000
--- a/reference/constraints/ExpressionLanguageSyntax.rst
+++ /dev/null
@@ -1,127 +0,0 @@
-ExpressionLanguageSyntax
-========================
-
-.. deprecated:: 6.1
-
-    This constraint is deprecated since Symfony 6.1. Instead, use the
-    :doc:`ExpressionSyntax </reference/constraints/ExpressionSyntax>` constraint.
-
-This constraint checks that the value is valid as an `ExpressionLanguage`_
-expression.
-
-==========  ===================================================================
-Applies to  :ref:`property or method <validation-property-target>`
-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-attributes
-
-        // src/Entity/Order.php
-        namespace App\Entity;
-
-        use Symfony\Component\Validator\Constraints as Assert;
-
-        class Order
-        {
-            #[Assert\ExpressionLanguageSyntax]
-            protected string  $promotion;
-
-            #[Assert\ExpressionLanguageSyntax(
-                allowedVariables: ['user', 'shipping_centers'],
-            )]
-            protected string $shippingOptions;
-        }
-
-    .. code-block:: yaml
-
-        # config/validator/validation.yaml
-        App\Entity\Order:
-            properties:
-                promotion:
-                    - ExpressionLanguageSyntax: ~
-                shippingOptions:
-                    - ExpressionLanguageSyntax:
-                        allowedVariables: ['user', 'shipping_centers']
-
-    .. code-block:: xml
-
-        <!-- config/validator/validation.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
-
-            <class name="App\Entity\Order">
-                <property name="promotion">
-                    <constraint name="ExpressionLanguageSyntax"/>
-                </property>
-                <property name="shippingOptions">
-                    <constraint name="ExpressionLanguageSyntax">
-                        <option name="allowedVariables">
-                            <value>user</value>
-                            <value>shipping_centers</value>
-                        </option>
-                    </constraint>
-                </property>
-            </class>
-        </constraint-mapping>
-
-    .. 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): void
-            {
-                $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/ExpressionSyntax.rst b/reference/constraints/ExpressionSyntax.rst
index 2a603eaa616..c1d086790c1 100644
--- a/reference/constraints/ExpressionSyntax.rst
+++ b/reference/constraints/ExpressionSyntax.rst
@@ -4,12 +4,6 @@ ExpressionSyntax
 This constraint checks that the value is valid as an `ExpressionLanguage`_
 expression.
 
-.. versionadded:: 6.1
-
-    This constraint was introduced in Symfony 6.1 and deprecates the previous
-    :doc:`ExpressionLanguageSyntax </reference/constraints/ExpressionLanguageSyntax>`
-    constraint.
-
 ==========  ===================================================================
 Applies to  :ref:`property or method <validation-property-target>`
 Class       :class:`Symfony\\Component\\Validator\\Constraints\\ExpressionSyntax`

From fc0b8994ec5e153c3fb8e2572c832a142d6cc30f Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 4 Jul 2023 14:15:16 +0200
Subject: [PATCH 008/747] [Security] Remove `{username}` occurrence

---
 security/ldap.rst | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/security/ldap.rst b/security/ldap.rst
index b2f5a3e753c..21ea66f480e 100644
--- a/security/ldap.rst
+++ b/security/ldap.rst
@@ -290,11 +290,6 @@ string will be replaced by the value of the ``uid_key`` configuration value
 (by default, ``sAMAccountName``), and the ``{user_identifier}`` string will be
 replaced by the user identified you are trying to load.
 
-.. deprecated:: 6.2
-
-    Starting from Symfony 6.2, the ``{username}`` string was deprecated in favor
-    of ``{user_identifier}``.
-
 For example, with a ``uid_key`` of ``uid``, and if you are trying to
 load the user ``fabpot``, the final string will be: ``(uid=fabpot)``.
 

From f24c16038a8410b66f8d45553a1659084687af95 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 5 Jul 2023 09:10:28 +0200
Subject: [PATCH 009/747] [Validator] Remove the deprecated
 VALIDATION_MODE_LOOSE

---
 reference/configuration/framework.rst |  7 +------
 reference/constraints/Email.rst       | 10 +---------
 2 files changed, 2 insertions(+), 15 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 74de9fc1094..5c7eafe5531 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -2619,12 +2619,7 @@ constraint verifies the submitted string entropy is matching the minimum entropy
 email_validation_mode
 .....................
 
-**type**: ``string`` **default**: ``loose``
-
-.. deprecated:: 6.2
-
-    The ``loose`` default value is deprecated since Symfony 6.2. Starting from
-    Symfony 7.0, the default value of this option will be ``html5``.
+**type**: ``string`` **default**: ``html5``
 
 Sets the default value for the
 :ref:`"mode" option of the Email validator <reference-constraint-email-mode>`.
diff --git a/reference/constraints/Email.rst b/reference/constraints/Email.rst
index 19b1579b88a..3f4207471c1 100644
--- a/reference/constraints/Email.rst
+++ b/reference/constraints/Email.rst
@@ -104,13 +104,10 @@ Parameter        Description
 ``mode``
 ~~~~~~~~
 
-**type**: ``string`` **default**: (see below)
+**type**: ``string`` **default**: ``html5``
 
 This option defines the pattern used to validate the email address. Valid values are:
 
-* ``loose`` uses a simple regular expression (just checks that at least one ``@``
-  character is present, etc.). This validation is too simple and it's recommended
-  to use one of the other modes instead;
 * ``html5`` uses the regular expression of the `HTML5 email input element`_,
   except it enforces a tld to be present.
 * ``html5-allow-no-tld`` uses exactly the same regular expression as the `HTML5 email input element`_,
@@ -133,11 +130,6 @@ The default value used by this option is set in the
 :ref:`framework.validation.email_validation_mode <reference-validation-email_validation_mode>`
 configuration option.
 
-.. deprecated:: 6.2
-
-    The ``loose`` value is deprecated since Symfony 6.2. Starting from
-    Symfony 7.0, the default value of this option will be ``html5``.
-
 .. include:: /reference/constraints/_normalizer-option.rst.inc
 
 .. include:: /reference/constraints/_payload-option.rst.inc

From bf08b822825de7d8272ef47a76f159133a6f9252 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 5 Jul 2023 13:08:30 +0200
Subject: [PATCH 010/747] [Form] Remove the deprecated renderForm() shortcut

---
 forms.rst | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/forms.rst b/forms.rst
index 806d1f47bb2..3c062c76e98 100644
--- a/forms.rst
+++ b/forms.rst
@@ -282,13 +282,6 @@ Now that the form has been created, the next step is to render it::
 Internally, the ``render()`` method calls ``$form->createView()`` to
 transform the form into a *form view* instance.
 
-.. deprecated:: 6.2
-
-    Prior to Symfony 6.2, you had to use ``$this->render(..., ['form' => $form->createView()])``
-    or the ``renderForm()`` method to render the form. The ``renderForm()``
-    method is deprecated in favor of directly passing the ``FormInterface``
-    instance to ``render()``.
-
 Then, use some :ref:`form helper functions <reference-form-twig-functions>` to
 render the form contents:
 

From e6f6bbd9f584083ed327dd967de582bca7508a9a Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Wed, 5 Jul 2023 14:02:31 +0200
Subject: [PATCH 011/747] Remove `terminate_on_cache_hit` option.

---
 reference/configuration/framework.rst | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 0b8fd4b0bac..82e87b67f0b 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -167,27 +167,6 @@ which the cache can serve a stale response when an error is encountered
 (default: 60). This setting is overridden by the stale-if-error HTTP
 Cache-Control extension (see RFC 5861).
 
-terminate_on_cache_hit
-......................
-
-**type**: ``boolean`` **default**: ``true``
-
-If ``true``, the :ref:`kernel.terminate <component-http-kernel-kernel-terminate>`
-event is dispatched even when the cache is hit.
-
-Unless your application needs to process events on cache hits, it's recommended
-to set this to ``false`` to improve performance, because it avoids having to
-bootstrap the Symfony framework on a cache hit.
-
-.. versionadded:: 6.2
-
-    The ``terminate_on_cache_hit`` option was introduced in Symfony 6.2.
-
-.. deprecated:: 6.2
-
-    Setting the ``terminate_on_cache_hit`` option to ``true`` was deprecated in
-    Symfony 6.2 and the option will be removed in Symfony 7.0.
-
  .. _configuration-framework-http_method_override:
 
 http_method_override

From 1ef9746c19cb52993f6b706dd398e6ca2ae45a5d Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 5 Jul 2023 14:58:01 +0200
Subject: [PATCH 012/747] [Form] Update the default value of widget option in
 date/time types

---
 reference/forms/types/options/date_widget_description.rst.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/forms/types/options/date_widget_description.rst.inc b/reference/forms/types/options/date_widget_description.rst.inc
index b86bdde5a0e..956ad8c7148 100644
--- a/reference/forms/types/options/date_widget_description.rst.inc
+++ b/reference/forms/types/options/date_widget_description.rst.inc
@@ -1,4 +1,4 @@
-**type**: ``string`` **default**: ``choice``
+**type**: ``string`` **default**: ``single_text``
 
 The basic way in which this field should be rendered. Can be one of the
 following:

From 16cb242026fa13653de2922dbed9a9194afb6348 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 5 Jul 2023 15:39:43 +0200
Subject: [PATCH 013/747] [Twig] Remove the deprecated autoescape option

---
 reference/configuration/twig.rst | 31 -------------------------------
 1 file changed, 31 deletions(-)

diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst
index cc079da6745..d36584a7f6c 100644
--- a/reference/configuration/twig.rst
+++ b/reference/configuration/twig.rst
@@ -33,37 +33,6 @@ compiled again automatically.
 
 .. _config-twig-autoescape:
 
-autoescape
-~~~~~~~~~~
-
-.. deprecated:: 6.1
-
-    This option is deprecated since Symfony 6.1. If required, use the
-    ``autoescape_service`` or ``autoescape_service_method`` option instead.
-
-**type**: ``boolean`` or ``string`` **default**: ``name``
-
-If set to ``false``, automatic escaping is disabled (you can still escape each content
-individually in the templates).
-
-.. caution::
-
-    Setting this option to ``false`` is dangerous and it will make your
-    application vulnerable to `XSS attacks`_ because most third-party bundles
-    assume that auto-escaping is enabled and they don't escape contents
-    themselves.
-
-If set to a string, the template contents are escaped using the strategy with
-that name. Allowed values are ``html``, ``js``, ``css``, ``url``, ``html_attr``
-and ``name``. The default value is ``name``. This strategy escapes contents
-according to the template name extension (e.g. it uses ``html`` for ``*.html.twig``
-templates and ``js`` for ``*.js.twig`` templates).
-
-.. tip::
-
-    See `autoescape_service`_ and `autoescape_service_method`_ to define your
-    own escaping strategy.
-
 autoescape_service
 ~~~~~~~~~~~~~~~~~~
 

From 88408715d43bf8d3c16a7e17ef5a3812be078f54 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 5 Jul 2023 18:16:24 +0200
Subject: [PATCH 014/747] [Messenger] Remove remaining deprecations

---
 messenger.rst                | 12 ------------
 messenger/multiple_buses.rst |  3 ---
 2 files changed, 15 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index 5a84e517415..95ae08a8ea8 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1718,12 +1718,6 @@ during a request::
         }
     }
 
-.. versionadded:: 6.3
-
-    The namespace of the ``InMemoryTransport`` class changed in Symfony 6.3 from
-    ``Symfony\Component\Messenger\Transport\InMemoryTransport`` to
-    ``Symfony\Component\Messenger\Transport\InMemory\InMemoryTransport``.
-
 The transport has a number of options:
 
 ``serialize`` (boolean, default: ``false``)
@@ -2020,12 +2014,6 @@ A single handler class can handle multiple messages. For that add the
         }
     }
 
-.. deprecated:: 6.2
-
-    Implementing the :class:`Symfony\\Component\\Messenger\\Handler\\MessageSubscriberInterface`
-    is another way to handle multiple messages with one handler class. This
-    interface was deprecated in Symfony 6.2.
-
 Binding Handlers to Different Transports
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/messenger/multiple_buses.rst b/messenger/multiple_buses.rst
index 49e4d3e568e..42ff8dc85d4 100644
--- a/messenger/multiple_buses.rst
+++ b/messenger/multiple_buses.rst
@@ -133,9 +133,6 @@ you can restrict each handler to a specific bus using the ``messenger.message_ha
         services:
             App\MessageHandler\SomeCommandHandler:
                 tags: [{ name: messenger.message_handler, bus: command.bus }]
-                # prevent handlers from being registered twice (or you can remove
-                # the MessageHandlerInterface that autoconfigure uses to find handlers)
-                autoconfigure: false
 
     .. code-block:: xml
 

From db47478951f9f0aa3eb643a7a6864e9e2e569170 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Thu, 6 Jul 2023 13:08:03 +0200
Subject: [PATCH 015/747] [Serializer] Add needed method and return types

---
 serializer/custom_normalizer.rst | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/serializer/custom_normalizer.rst b/serializer/custom_normalizer.rst
index 0168e0c7447..7534002da20 100644
--- a/serializer/custom_normalizer.rst
+++ b/serializer/custom_normalizer.rst
@@ -30,7 +30,7 @@ to customize the normalized data. To do that, leverage the ``ObjectNormalizer``:
         ) {
         }
 
-        public function normalize($topic, string $format = null, array $context = [])
+        public function normalize($topic, string $format = null, array $context = []): array
         {
             $data = $this->normalizer->normalize($topic, $format, $context);
 
@@ -42,10 +42,17 @@ to customize the normalized data. To do that, leverage the ``ObjectNormalizer``:
             return $data;
         }
 
-        public function supportsNormalization($data, string $format = null, array $context = [])
+        public function supportsNormalization($data, string $format = null, array $context = []): bool
         {
             return $data instanceof Topic;
         }
+
+        public function getSupportedTypes(?string $format): array
+        {
+            return [
+                Topic::class => true,
+            ];
+        }
     }
 
 Registering it in your Application

From e4f0386293dcdbae694ca7b16112276e4301b659 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Thu, 6 Jul 2023 18:57:16 +0200
Subject: [PATCH 016/747] [Lock] Remove deprecated option

---
 components/lock.rst | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/components/lock.rst b/components/lock.rst
index 293eaeed84e..f92d024aac8 100644
--- a/components/lock.rst
+++ b/components/lock.rst
@@ -474,18 +474,12 @@ The ``MongoDbStore`` takes the following ``$options`` (depending on the first pa
 Option          Description
 ==============  ================================================================================================
 gcProbability  Should a TTL Index be created expressed as a probability from 0.0 to 1.0 (Defaults to ``0.001``)
-gcProbablity   Same as ``gcProbability``, see the deprecation note below
 database       The name of the database
 collection     The name of the collection
 uriOptions     Array of URI options for `MongoDBClient::__construct`_
 driverOptions  Array of driver options for `MongoDBClient::__construct`_
 =============  ================================================================================================
 
-.. deprecated:: 6.3
-
-    The ``gcProbablity`` option (notice the typo in its name) is deprecated since
-    Symfony 6.3, use the ``gcProbability`` option instead.
-
 When the first parameter is a:
 
 ``MongoDB\Collection``:

From a3e5a060e970e0ec63183ac4fbd81871d958b95a Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 5 Jul 2023 15:35:41 +0200
Subject: [PATCH 017/747] [Translation] Update the PHP extraction information
 for Symfony 7.0

---
 reference/dic_tags.rst | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/reference/dic_tags.rst b/reference/dic_tags.rst
index 7b953e20e3c..b003ca683b2 100644
--- a/reference/dic_tags.rst
+++ b/reference/dic_tags.rst
@@ -1071,23 +1071,16 @@ file
 
 When executing the ``translation:extract`` command, it uses extractors to
 extract translation messages from a file. By default, the Symfony Framework
-has a :class:`Symfony\\Bridge\\Twig\\Translation\\TwigExtractor` and a PHP
-extractor to find and extract translation keys from Twig templates and PHP files.
+has a :class:`Symfony\\Bridge\\Twig\\Translation\\TwigExtractor` to find and
+extract translation keys from Twig templates.
 
-Symfony includes two PHP extractors: :class:`Symfony\\Component\\Translation\\Extractor\\PhpExtractor`
-and :class:`Symfony\\Component\\Translation\\Extractor\\PhpAstExtractor`. The
-first one is simple but doesn't require to install any packages; the second one
-is much more advanced, but requires to install this dependency in your project:
+If you also want to find and extract translation keys from PHP files, install
+the following dependency to activate the :class:`Symfony\\Component\\Translation\\Extractor\\PhpAstExtractor`:
 
 .. code-block:: terminal
 
     $ composer require nikic/php-parser
 
-.. deprecated:: 6.2
-
-    The ``PhpExtractor`` class is deprecated since Symfony 6.2. The ``PhpAstExtractor``
-    class will be the only PHP extractor available starting from Symfony 7.0.
-
 You can create your own extractor by creating a class that implements
 :class:`Symfony\\Component\\Translation\\Extractor\\ExtractorInterface`
 and tagging the service with ``translation.extractor``. The tag has one

From 699a89fa7c1f7b694171287634c3d8e90e2b58c8 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 5 Jul 2023 15:05:23 +0200
Subject: [PATCH 018/747] Update the default value of the http_method_override
 option

---
 reference/configuration/framework.rst | 14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 03f46ae6d31..d7431bb264d 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -172,7 +172,7 @@ Cache-Control extension (see RFC 5861).
 http_method_override
 ~~~~~~~~~~~~~~~~~~~~
 
-**type**: ``boolean`` **default**: (see explanation below)
+**type**: ``boolean`` **default**: ``false``
 
 This determines whether the ``_method`` request parameter is used as the
 intended HTTP method on POST requests. If enabled, the
@@ -180,18 +180,6 @@ intended HTTP method on POST requests. If enabled, the
 method gets called automatically. It becomes the service container parameter
 named ``kernel.http_method_override``.
 
-The **default value** is:
-
-* ``true``, if you have an existing application that you've upgraded from an older
-  Symfony version without resyncing the :doc:`Symfony Flex </setup/flex>` recipes;
-* ``false``, if you've created a new Symfony application or updated the Symfony
-  Flex recipes. This is also the default value starting from Symfony 7.0.
-
-.. deprecated:: 6.1
-
-    Not setting a value explicitly for this option is deprecated since Symfony 6.1
-    because the default value will change to ``false`` in Symfony 7.0.
-
 .. seealso::
 
     :ref:`Changing the Action and HTTP Method <forms-change-action-method>` of

From 039ba692a58e81ff5fb2c010789740b8d550688d Mon Sep 17 00:00:00 2001
From: Gary PEGEOT <garypegeot@gmail.com>
Date: Mon, 10 Jul 2023 09:30:03 +0200
Subject: [PATCH 019/747] [HTTPClient] Add documentation for
 `HarFileResponseFactory`

Fixes https://github.com/symfony/symfony-docs/issues/18546
---
 http_client.rst | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/http_client.rst b/http_client.rst
index 3dd9e867bc1..c11bde2d15c 100644
--- a/http_client.rst
+++ b/http_client.rst
@@ -2196,6 +2196,45 @@ test it in a real application::
         }
     }
 
+Testing using HAR files
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The previous example can also be achieved using `HAR`_ files. You can export those files from all modern browsers (from the network tab) &
+HTTP Clients. First, do the HTTP request(s) you want to test in your favorite HTTP Client / Browser, then store generated ``.har`` file somewhere in your application::
+
+    // ExternalArticleServiceTest.php
+    use PHPUnit\Framework\TestCase;
+    use Symfony\Component\HttpClient\MockHttpClient;
+    use Symfony\Component\HttpClient\Response\MockResponse;
+
+    final class ExternalArticleServiceTest extends TestCase
+    {
+        public function testSubmitData(): void
+        {
+            // Arrange
+            $fixtureDir = sprintf('%s/tests/fixtures/HTTP', static::getContainer()->getParameter('kernel.project_dir'));
+            $factory = new HarFileResponseFactory("$fixtureDir/example.com_archive.har");
+            $httpClient = new MockHttpClient($factory, 'https://example.com');
+            $service = new ExternalArticleService($httpClient);
+
+            // Act
+            $responseData = $service->createArticle($requestData);
+
+            // Assert
+            self::assertSame($responseData, 'the expected response');
+        }
+    }
+
+
+If your service does multiple requests or if your `.har` file contains multiple request / response pairs,
+the :class:`Symfony\\Component\\HttpClient\\Test\\HarFileResponseFactory` will find the associated response based on
+the request method, url and body (if any). Note that **this doesn't work** if the request body or uri is random / always changing
+(if it contains current date or random UUID(s) for example).
+
+.. versionadded:: 7.0
+
+    The ``HarFileResponseFactory`` was introduced in Symfony 7.0.
+
 Testing Network Transport Exceptions
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -2262,3 +2301,4 @@ you to do so, by yielding the exception from its body::
 .. _`idempotent method`: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods
 .. _`SSRF`: https://portswigger.net/web-security/ssrf
 .. _`RFC 6570`: https://www.rfc-editor.org/rfc/rfc6570
+.. _`HAR`: https://w3c.github.io/web-performance/specs/HAR/Overview.html

From bc8d4763b700a138463629b50aa685ae160b9924 Mon Sep 17 00:00:00 2001
From: Maxime Doutreluingne <maxime.doutreluingne@gmail.com>
Date: Sun, 9 Jul 2023 11:05:12 +0200
Subject: [PATCH 020/747] [Notifier] Remove the Sendinblue bridge

---
 notifier.rst                     | 2 --
 reference/configuration/twig.rst | 1 -
 2 files changed, 3 deletions(-)

diff --git a/notifier.rst b/notifier.rst
index 27a10a2a766..626b23f14f1 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -85,7 +85,6 @@ Service             Package                                DSN
 `Redlink`_          ``symfony/redlink-notifier``           ``redlink://API_KEY:APP_KEY@default?from=SENDER_NAME&version=API_VERSION``
 `RingCentral`_      ``symfony/ring-central-notifier``      ``ringcentral://API_TOKEN@default?from=FROM``
 `Sendberry`_        ``symfony/sendberry-notifier``         ``sendberry://USERNAME:PASSWORD@default?auth_key=AUTH_KEY&from=FROM``
-`Sendinblue`_       ``symfony/sendinblue-notifier``        ``sendinblue://API_KEY@default?sender=PHONE``
 `Sms77`_            ``symfony/sms77-notifier``             ``sms77://API_KEY@default?from=FROM``
 `SimpleTextin`_     ``symfony/simple-textin-notifier``     ``simpletextin://API_KEY@default?from=FROM``
 `Sinch`_            ``symfony/sinch-notifier``             ``sinch://ACCOUNT_ID:AUTH_TOKEN@default?from=FROM``
@@ -1024,7 +1023,6 @@ is dispatched. Listeners receive a
 .. _`RocketChat`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/RocketChat/README.md
 .. _`SMSFactor`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SmsFactor/README.md
 .. _`Sendberry`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sendberry/README.md
-.. _`Sendinblue`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sendinblue/README.md
 .. _`SimpleTextin`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SimpleTextin/README.md
 .. _`Sinch`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sinch/README.md
 .. _`Slack`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Slack/README.md
diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst
index d36584a7f6c..6de8ef24742 100644
--- a/reference/configuration/twig.rst
+++ b/reference/configuration/twig.rst
@@ -402,4 +402,3 @@ attribute or method doesn't exist. If set to ``false`` these errors are ignored
 and the non-existing values are replaced by ``null``.
 
 .. _`the optimizer extension`: https://twig.symfony.com/doc/3.x/api.html#optimizer-extension
-.. _`XSS attacks`: https://en.wikipedia.org/wiki/Cross-site_scripting

From ec88f6d96d136b603388326209e84bf131b121b9 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 10 Jul 2023 11:48:50 +0200
Subject: [PATCH 021/747] Tweaks

---
 notifier.rst | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/notifier.rst b/notifier.rst
index a8ddf6374c0..47aad3d263a 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -121,11 +121,6 @@ Service             Package                                DSN
 
     The `Redlink`_ and `Brevo`_ integrations were introduced in Symfony 6.4.
 
-.. deprecated:: 6.4
-
-    The `Sendinblue`_ integration is deprecated since
-    Symfony 6.4, use the `Brevo`_ integration instead.
-
 To enable a texter, add the correct DSN in your ``.env`` file and
 configure the ``texter_transports``:
 

From 71f2f821de2a8f28c456152cb54b531670947a53 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 10 Jul 2023 13:18:01 +0200
Subject: [PATCH 022/747] Minor rewords

---
 http_client.rst | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/http_client.rst b/http_client.rst
index c11bde2d15c..bc0a17b581a 100644
--- a/http_client.rst
+++ b/http_client.rst
@@ -2196,11 +2196,15 @@ test it in a real application::
         }
     }
 
-Testing using HAR files
+Testing Using HAR Files
 ~~~~~~~~~~~~~~~~~~~~~~~
 
-The previous example can also be achieved using `HAR`_ files. You can export those files from all modern browsers (from the network tab) &
-HTTP Clients. First, do the HTTP request(s) you want to test in your favorite HTTP Client / Browser, then store generated ``.har`` file somewhere in your application::
+Modern browsers (via their network tab) and HTTP clients allow to export the
+information of one or more HTTP requests using the `HAR`_ (HTTP Archive) format.
+You can use those ``.har`` files to perform tests with Symfony's HTTP Client.
+
+First, use a browser or HTTP client to perform the HTTP request(s) you want to
+test. Then, save that information as a ``.har`` file somewhere in your application::
 
     // ExternalArticleServiceTest.php
     use PHPUnit\Framework\TestCase;
@@ -2225,11 +2229,11 @@ HTTP Clients. First, do the HTTP request(s) you want to test in your favorite HT
         }
     }
 
-
-If your service does multiple requests or if your `.har` file contains multiple request / response pairs,
-the :class:`Symfony\\Component\\HttpClient\\Test\\HarFileResponseFactory` will find the associated response based on
-the request method, url and body (if any). Note that **this doesn't work** if the request body or uri is random / always changing
-(if it contains current date or random UUID(s) for example).
+If your service performs multiple requests or if your ``.har`` file contains multiple
+request/response pairs, the :class:`Symfony\\Component\\HttpClient\\Test\\HarFileResponseFactory`
+will find the associated response based on the request method, URL and body (if any).
+Note that **this won't work** if the request body or URI is random / always
+changing (e.g. if it contains current date or random UUIDs).
 
 .. versionadded:: 7.0
 

From 0068934b5c574e1a611d4f84eb8291bbab356f91 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 11 Jul 2023 16:42:40 +0200
Subject: [PATCH 023/747] [Bridges][Bundles] Convert to native return types

---
 bundles/configuration.rst                       | 4 ++--
 bundles/extension.rst                           | 2 +-
 bundles/prepend_extension.rst                   | 2 +-
 components/console/changing_default_command.rst | 6 ++++--
 components/console/console_arguments.rst        | 4 ++--
 components/console/logger.rst                   | 4 +++-
 components/dependency_injection/compilation.rst | 2 +-
 configuration/using_parameters_in_dic.rst       | 2 +-
 console/calling_commands.rst                    | 2 +-
 console/verbosity.rst                           | 2 +-
 logging/monolog_console.rst                     | 4 +++-
 session.rst                                     | 4 ++--
 12 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/bundles/configuration.rst b/bundles/configuration.rst
index bc9efc1e0b9..366eec0d72c 100644
--- a/bundles/configuration.rst
+++ b/bundles/configuration.rst
@@ -458,7 +458,7 @@ the extension. You might want to change this to a more professional URL::
     {
         // ...
 
-        public function getNamespace()
+        public function getNamespace(): string
         {
             return 'http://acme_company.com/schema/dic/hello';
         }
@@ -490,7 +490,7 @@ can place it anywhere you like. You should return this path as the base path::
     {
         // ...
 
-        public function getXsdValidationBasePath()
+        public function getXsdValidationBasePath(): string
         {
             return __DIR__.'/../Resources/config/schema';
         }
diff --git a/bundles/extension.rst b/bundles/extension.rst
index f831efdaf5b..82c8fb05183 100644
--- a/bundles/extension.rst
+++ b/bundles/extension.rst
@@ -34,7 +34,7 @@ This is how the extension of an AcmeHelloBundle should look like::
 
     class AcmeHelloExtension extends Extension
     {
-        public function load(array $configs, ContainerBuilder $container)
+        public function load(array $configs, ContainerBuilder $container): void
         {
             // ... you'll load the files here later
         }
diff --git a/bundles/prepend_extension.rst b/bundles/prepend_extension.rst
index 8d28080470f..b94b647671e 100644
--- a/bundles/prepend_extension.rst
+++ b/bundles/prepend_extension.rst
@@ -31,7 +31,7 @@ To give an Extension the power to do this, it needs to implement
     {
         // ...
 
-        public function prepend(ContainerBuilder $container)
+        public function prepend(ContainerBuilder $container): void
         {
             // ...
         }
diff --git a/components/console/changing_default_command.rst b/components/console/changing_default_command.rst
index f8b100993a9..b739e3b39ba 100644
--- a/components/console/changing_default_command.rst
+++ b/components/console/changing_default_command.rst
@@ -15,14 +15,16 @@ name to the ``setDefaultCommand()`` method::
     #[AsCommand(name: 'hello:world')]
     class HelloWorldCommand extends Command
     {
-        protected function configure()
+        protected function configure(): void
         {
             $this->setDescription('Outputs "Hello World"');
         }
 
-        protected function execute(InputInterface $input, OutputInterface $output)
+        protected function execute(InputInterface $input, OutputInterface $output): int
         {
             $output->writeln('Hello World');
+
+            return Command::SUCCESS;
         }
     }
 
diff --git a/components/console/console_arguments.rst b/components/console/console_arguments.rst
index d7bf141f4ce..da538ac78f1 100644
--- a/components/console/console_arguments.rst
+++ b/components/console/console_arguments.rst
@@ -22,7 +22,7 @@ Have a look at the following command that has three options::
     #[AsCommand(name: 'demo:args', description: 'Describe args behaviors')]
     class DemoArgsCommand extends Command
     {
-        protected function configure()
+        protected function configure(): void
         {
             $this
                 ->setDefinition(
@@ -34,7 +34,7 @@ Have a look at the following command that has three options::
                 );
         }
 
-        protected function execute(InputInterface $input, OutputInterface $output)
+        protected function execute(InputInterface $input, OutputInterface $output): int
         {
             // ...
         }
diff --git a/components/console/logger.rst b/components/console/logger.rst
index afeab7dd0cb..5aa72a9d02d 100644
--- a/components/console/logger.rst
+++ b/components/console/logger.rst
@@ -44,12 +44,14 @@ You can rely on the logger to use this dependency inside a command::
     )]
     class MyCommand extends Command
     {
-        protected function execute(InputInterface $input, OutputInterface $output)
+        protected function execute(InputInterface $input, OutputInterface $output): int
         {
             $logger = new ConsoleLogger($output);
 
             $myDependency = new MyDependency($logger);
             $myDependency->doStuff();
+
+            return Command::SUCCESS;
         }
     }
 
diff --git a/components/dependency_injection/compilation.rst b/components/dependency_injection/compilation.rst
index 1f450df28ed..64209c1586c 100644
--- a/components/dependency_injection/compilation.rst
+++ b/components/dependency_injection/compilation.rst
@@ -408,7 +408,7 @@ class implementing the ``CompilerPassInterface``::
 
     class CustomPass implements CompilerPassInterface
     {
-        public function process(ContainerBuilder $container)
+        public function process(ContainerBuilder $container): void
         {
             // ... do something during the compilation
         }
diff --git a/configuration/using_parameters_in_dic.rst b/configuration/using_parameters_in_dic.rst
index 05008114e01..259a0b9d974 100644
--- a/configuration/using_parameters_in_dic.rst
+++ b/configuration/using_parameters_in_dic.rst
@@ -135,7 +135,7 @@ And set it in the constructor of ``Configuration`` via the ``Extension`` class::
     {
         // ...
 
-        public function getConfiguration(array $config, ContainerBuilder $container)
+        public function getConfiguration(array $config, ContainerBuilder $container): Configuration
         {
             return new Configuration($container->getParameter('kernel.debug'));
         }
diff --git a/console/calling_commands.rst b/console/calling_commands.rst
index 001dc47e35e..089688767fe 100644
--- a/console/calling_commands.rst
+++ b/console/calling_commands.rst
@@ -27,7 +27,7 @@ method)::
     {
         // ...
 
-        protected function execute(InputInterface $input, OutputInterface $output): void
+        protected function execute(InputInterface $input, OutputInterface $output): int
         {
             $command = $this->getApplication()->find('demo:greet');
 
diff --git a/console/verbosity.rst b/console/verbosity.rst
index 7df68d30f23..f7a1a1e5e59 100644
--- a/console/verbosity.rst
+++ b/console/verbosity.rst
@@ -69,7 +69,7 @@ level. For example::
                 OutputInterface::VERBOSITY_VERBOSE
             );
 
-            return 0;
+            return Command::SUCCESS;
         }
     }
 
diff --git a/logging/monolog_console.rst b/logging/monolog_console.rst
index ad06cfabbff..8d296883b50 100644
--- a/logging/monolog_console.rst
+++ b/logging/monolog_console.rst
@@ -47,10 +47,12 @@ The example above could then be rewritten as::
         ) {
         }
 
-        protected function execute(InputInterface $input, OutputInterface $output)
+        protected function execute(InputInterface $input, OutputInterface $output): int
         {
             $this->logger->debug('Some info');
             $this->logger->notice('Some more info');
+
+            return Command::SUCCESS;
         }
     }
 
diff --git a/session.rst b/session.rst
index 1dcbaa71b4b..2f8848f860b 100644
--- a/session.rst
+++ b/session.rst
@@ -1464,7 +1464,7 @@ event::
         ) {
         }
 
-        public function onInteractiveLogin(InteractiveLoginEvent $event)
+        public function onInteractiveLogin(InteractiveLoginEvent $event): void
         {
             $user = $event->getAuthenticationToken()->getUser();
 
@@ -1473,7 +1473,7 @@ event::
             }
         }
 
-        public static function getSubscribedEvents()
+        public static function getSubscribedEvents(): array
         {
             return [
                 SecurityEvents::INTERACTIVE_LOGIN => 'onInteractiveLogin',

From 7b9f807a7b56e1886530865504dda235a0d779e1 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 17 Jul 2023 13:38:11 +0200
Subject: [PATCH 024/747] [Serializer] Remove
 `CacheableSupportsMethodInterface`

---
 serializer/custom_normalizer.rst | 41 ++++----------------------------
 1 file changed, 5 insertions(+), 36 deletions(-)

diff --git a/serializer/custom_normalizer.rst b/serializer/custom_normalizer.rst
index ec121a2f54b..25528fff54e 100644
--- a/serializer/custom_normalizer.rst
+++ b/serializer/custom_normalizer.rst
@@ -63,8 +63,8 @@ a service and :doc:`tagged </service_container/tags>` with ``serializer.normaliz
 If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`,
 this is done automatically!
 
-Performance
------------
+Performance of Normalizers/Denormalizers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 To figure which normalizer (or denormalizer) must be used to handle an object,
 the :class:`Symfony\\Component\\Serializer\\Serializer` class will call the
@@ -72,39 +72,10 @@ the :class:`Symfony\\Component\\Serializer\\Serializer` class will call the
 (or :method:`Symfony\\Component\\Serializer\\Normalizer\\DenormalizerInterface::supportsDenormalization`)
 of all registered normalizers (or denormalizers) in a loop.
 
-The result of these methods can vary depending on the object to serialize, the
-format and the context. That's why the result **is not cached** by default and
-can result in a significant performance bottleneck.
-
-However, most normalizers (and denormalizers) always return the same result when
-the object's type and the format are the same, so the result can be cached. To
-do so, make those normalizers (and denormalizers) implement the
-:class:`Symfony\\Component\\Serializer\\Normalizer\\CacheableSupportsMethodInterface`
-and return ``true`` when
-:method:`Symfony\\Component\\Serializer\\Normalizer\\CacheableSupportsMethodInterface::hasCacheableSupportsMethod`
-is called.
-
-.. note::
-
-    All built-in :ref:`normalizers and denormalizers <component-serializer-normalizers>`
-    as well the ones included in `API Platform`_ natively implement this interface.
-
-.. deprecated:: 6.3
-
-    The :class:`Symfony\\Component\\Serializer\\Normalizer\\CacheableSupportsMethodInterface`
-    interface is deprecated since Symfony 6.3. You should implement the
-    ``getSupportedTypes()`` method instead, as shown in the section below.
-
-Improving Performance of Normalizers/Denormalizers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. versionadded:: 6.3
-
-    The ``getSupportedTypes()`` method was introduced in Symfony 6.3.
-
-Both :class:`Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface`
+Additionally, both
+:class:`Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface`
 and :class:`Symfony\\Component\\Serializer\\Normalizer\\DenormalizerInterface`
-contain a new method ``getSupportedTypes()``. This method allows normalizers or
+contain the ``getSupportedTypes()`` method. This method allows normalizers or
 denormalizers to declare the type of objects they can handle, and whether they
 are cacheable. With this info, even if the ``supports*()`` call is not cacheable,
 the Serializer can skip a ton of method calls to ``supports*()`` improving
@@ -148,5 +119,3 @@ Here is an example of how to use the ``getSupportedTypes()`` method::
 
 Note that ``supports*()`` method implementations should not assume that
 ``getSupportedTypes()`` has been called before.
-
-.. _`API Platform`: https://api-platform.com

From 0fd8f8fa532a3bafed52504670f4ad339b34a712 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 24 Jul 2023 14:21:18 +0200
Subject: [PATCH 025/747] [Serializer] Custom normalizer update

---
 serializer/custom_normalizer.rst | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/serializer/custom_normalizer.rst b/serializer/custom_normalizer.rst
index 25528fff54e..58e6ef2d075 100644
--- a/serializer/custom_normalizer.rst
+++ b/serializer/custom_normalizer.rst
@@ -12,7 +12,10 @@ Creating a New Normalizer
 Imagine you want add, modify, or remove some properties during the serialization
 process. For that you'll have to create your own normalizer. But it's usually
 preferable to let Symfony normalize the object, then hook into the normalization
-to customize the normalized data. To do that, leverage the ``ObjectNormalizer``::
+to customize the normalized data. To do that, leverage the
+``NormalizerAwareInterface`` and the ``NormalizerAwareTrait``. This will give
+you access to a ``$normalizer`` property which takes care of most of the
+normalization process::
 
     // src/Serializer/TopicNormalizer.php
     namespace App\Serializer;
@@ -20,13 +23,13 @@ to customize the normalized data. To do that, leverage the ``ObjectNormalizer``:
     use App\Entity\Topic;
     use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
     use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
 
-    class TopicNormalizer implements NormalizerInterface
+    class TopicNormalizer implements NormalizerInterface, NormalizerAwareInterface
     {
+        use NormalizerAwareTrait;
+
         public function __construct(
             private UrlGeneratorInterface $router,
-            private ObjectNormalizer $normalizer,
         ) {
         }
 

From 4927b6e38bf0cf6aefc1ddf50e5a15b92e583cd2 Mon Sep 17 00:00:00 2001
From: Jules Pietri <heahdude@yahoo.fr>
Date: Mon, 24 Jul 2023 15:45:26 +0200
Subject: [PATCH 026/747] [Security] Remove deprecated XML config

---
 security/custom_authenticator.rst | 2 +-
 security/entry_point.rst          | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/security/custom_authenticator.rst b/security/custom_authenticator.rst
index d9debbb1fb0..f2d7fb57c14 100644
--- a/security/custom_authenticator.rst
+++ b/security/custom_authenticator.rst
@@ -105,7 +105,7 @@ The authenticator can be enabled using the ``custom_authenticators`` setting:
                 http://symfony.com/schema/dic/security
                 https://symfony.com/schema/dic/security/security-1.0.xsd">
 
-            <config enable-authenticator-manager="true">
+            <config>
                 <!-- ... -->
 
                 <firewall name="main">
diff --git a/security/entry_point.rst b/security/entry_point.rst
index e99a4039fcb..b23f45db957 100644
--- a/security/entry_point.rst
+++ b/security/entry_point.rst
@@ -42,7 +42,7 @@ You can configure this using the ``entry_point`` setting:
                 http://symfony.com/schema/dic/security
                 https://symfony.com/schema/dic/security/security-1.0.xsd">
 
-            <config enable-authenticator-manager="true">
+            <config>
                 <!-- ... -->
 
                 <!-- entry-point: configure the form authentication as the entry

From 1b6d724554fd963ba1a38fccb4f2ee7b8c888654 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Fri, 28 Jul 2023 10:39:49 +0200
Subject: [PATCH 027/747] [MonologBridge] Remove support for monolog < 3.0

---
 logging/handlers.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/logging/handlers.rst b/logging/handlers.rst
index d44e3ab18a3..47bfb0f2aee 100644
--- a/logging/handlers.rst
+++ b/logging/handlers.rst
@@ -32,7 +32,7 @@ To use it, declare it as a service:
                     $endpoint: "http://127.0.0.1:9200"
                     $index: "monolog"
                     $client: null
-                    $level: !php/const Monolog\Logger::DEBUG
+                    $level: !php/enum Monolog\Level::Debug
                     $bubble: true
                     $elasticsearchVersion: '1.0.0'
 
@@ -56,7 +56,7 @@ To use it, declare it as a service:
                     <argument key="endpoint">http://127.0.0.1:9200</argument>
                     <argument key="index">monolog</argument>
                     <argument key="client"/>
-                    <argument key="level" type="constant">Monolog\Logger::DEBUG</argument>
+                    <argument key="level" type="enum">Monolog\Level::Debug</argument>
                     <argument key="bubble">true</argument>
                     <argument key="elasticsearchVersion">1.0.0</argument>
                 </service>
@@ -66,7 +66,7 @@ To use it, declare it as a service:
     .. code-block:: php
 
         // config/services.php
-        use Monolog\Logger;
+        use Monolog\Level;
         use Symfony\Bridge\Monolog\Handler\ElasticsearchLogstashHandler;
 
         $container->register(ElasticsearchLogstashHandler::class);
@@ -77,7 +77,7 @@ To use it, declare it as a service:
                 '$endpoint' => "http://127.0.0.1:9200",
                 '$index' => "monolog",
                 '$client' => null,
-                '$level' => Logger::DEBUG,
+                '$level' => Level::Debug,
                 '$bubble' => true,
                 '$elasticsearchVersion' => '1.0.0',
             )

From 674037b860f81b8d0b5fb39857ba0e178a9cbc80 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Thu, 22 Jun 2023 13:46:14 +0200
Subject: [PATCH 028/747] Remove all 6.x deprecations on 7.0

---
 components/console/events.rst                 |  10 --
 components/http_foundation.rst                |  11 +-
 components/validator/resources.rst            |   4 -
 console.rst                                   |  11 --
 contributing/documentation/format.rst         |   8 +-
 doctrine/events.rst                           | 165 +-----------------
 mailer.rst                                    |  14 +-
 messenger.rst                                 |   6 -
 reference/attributes.rst                      |   5 -
 reference/configuration/doctrine.rst          |  10 +-
 reference/formats/expression_language.rst     |   2 +-
 .../options/date_widget_description.rst.inc   |   5 -
 serializer/custom_normalizer.rst              |   9 -
 service_container/service_decoration.rst      |   6 -
 14 files changed, 19 insertions(+), 247 deletions(-)

diff --git a/components/console/events.rst b/components/console/events.rst
index 66e3cad013c..d7348996c94 100644
--- a/components/console/events.rst
+++ b/components/console/events.rst
@@ -255,16 +255,6 @@ handle all signals e.g. to do some tasks before terminating the command.
         The :class:`Symfony\\Component\\Console\\SignalRegistry\\SignalMap` class was
         introduced in Symfony 6.4.
 
-.. deprecated:: 6.3
-
-    In Symfony versions previous to 6.3, all signals (except ``SIGUSR1`` and
-    ``SIGUSR2``) would terminate the script by calling ``exit(0)``. Starting
-    from Symfony 6.3, no more signal is automatically calling ``exit(0)``.
-
-.. deprecated:: 6.3
-
-    Not returning a value in ``handleSignal()`` is deprecated since Symfony 6.3.
-
 .. _`reserved exit codes`: https://www.tldp.org/LDP/abs/html/exitcodes.html
 .. _`Signals`: https://en.wikipedia.org/wiki/Signal_(IPC)
 .. _`constants of the PCNTL PHP extension`: https://www.php.net/manual/en/pcntl.constants.php
diff --git a/components/http_foundation.rst b/components/http_foundation.rst
index 0e46d0648fa..28ddc307fa0 100644
--- a/components/http_foundation.rst
+++ b/components/http_foundation.rst
@@ -152,13 +152,10 @@ has some methods to filter the input values:
 
 :method:`Symfony\\Component\\HttpFoundation\\ParameterBag::filter`
     Filters the parameter by using the PHP :phpfunction:`filter_var` function.
-
-    .. deprecated:: 6.3
-
-        Ignoring invalid values when using ``filter()`` is deprecated and will throw
-        a :class:`Symfony\\Component\\HttpKernel\\Exception\\BadRequestHttpException`
-        in Symfony 7.0. You can use the ``FILTER_NULL_ON_FAILURE`` flag to keep
-        ignoring them.
+    If invalid values are found, a
+    :class:`Symfony\\Component\\HttpKernel\\Exception\\BadRequestHttpException`
+    is thrown. The ``FILTER_NULL_ON_FAILURE`` flag can be used to ignore invalid
+    values.
 
 All getters take up to two arguments: the first one is the parameter name
 and the second one is the default value to return if the parameter does not
diff --git a/components/validator/resources.rst b/components/validator/resources.rst
index 5dfacd3e48f..19b0c54b6ec 100644
--- a/components/validator/resources.rst
+++ b/components/validator/resources.rst
@@ -114,10 +114,6 @@ If you use annotations instead of attributes, it's also required to call
         ->addDefaultDoctrineAnnotationReader() // add this only when using annotations
         ->getValidator();
 
-.. deprecated:: 6.4
-
-    Annotations are deprecated since Symfony 6.4, use attributes instead.
-
 To disable the annotation loader after it was enabled, call
 :method:`Symfony\\Component\\Validator\\ValidatorBuilder::disableAnnotationMapping`.
 
diff --git a/console.rst b/console.rst
index a242d99904c..a887b2a340d 100644
--- a/console.rst
+++ b/console.rst
@@ -171,12 +171,6 @@ You can optionally define a description, help message and the
     ``setDescription()`` method instead of the attribute to define the command
     description.
 
-.. deprecated:: 6.1
-
-    The static property ``$defaultDescription`` was deprecated in Symfony 6.1.
-    Instead, use the ``#[AsCommand]`` attribute to define the optional command
-    description.
-
 The ``configure()`` method is called automatically at the end of the command
 constructor. If your command defines its own constructor, set the properties
 first and then call to the parent constructor, to make those properties
@@ -238,11 +232,6 @@ If you can't use PHP attributes, register the command as a service and
 :ref:`default services.yaml configuration <service-container-services-load-example>`,
 this is already done for you, thanks to :ref:`autoconfiguration <services-autoconfigure>`.
 
-.. deprecated:: 6.1
-
-    The static property ``$defaultName`` was deprecated in Symfony 6.1.
-    Define your command name with the ``#[AsCommand]`` attribute instead.
-
 Running the Command
 ~~~~~~~~~~~~~~~~~~~
 
diff --git a/contributing/documentation/format.rst b/contributing/documentation/format.rst
index 568a5a0620f..2402439fe8f 100644
--- a/contributing/documentation/format.rst
+++ b/contributing/documentation/format.rst
@@ -216,7 +216,7 @@ If you are documenting a brand new feature, a change or a deprecation that's
 been made in Symfony, you should precede your description of the change with
 the corresponding directive and a short description:
 
-For a new feature or a behavior change use the ``.. versionadded:: 6.x``
+For a new feature or a behavior change use the ``.. versionadded:: 7.x``
 directive:
 
 .. code-block:: rst
@@ -243,12 +243,12 @@ For a deprecation use the ``.. deprecated:: 6.x`` directive:
 
         ... ... ... was deprecated in Symfony 6.2.
 
-Whenever a new major version of Symfony is released (e.g. 6.0, 7.0, etc), a new
+Whenever a new major version of Symfony is released (e.g. 7.0, 8.0, etc), a new
 branch of the documentation is created from the ``x.4`` branch of the previous
 major version. At this point, all the ``versionadded`` and ``deprecated`` tags
 for Symfony versions that have a lower major version will be removed. For
-example, if Symfony 6.0 were released today, 5.0 to 5.4 ``versionadded`` and
-``deprecated`` tags would be removed from the new ``6.0`` branch.
+example, if Symfony 7.0 were released today, 6.0 to 6.4 ``versionadded`` and
+``deprecated`` tags would be removed from the new ``7.0`` branch.
 
 .. _reStructuredText: https://docutils.sourceforge.io/rst.html
 .. _Sphinx: https://www.sphinx-doc.org/
diff --git a/doctrine/events.rst b/doctrine/events.rst
index 6b445ef74ea..ce345643d83 100644
--- a/doctrine/events.rst
+++ b/doctrine/events.rst
@@ -15,7 +15,7 @@ There are different ways to listen to these Doctrine events:
 
 * **Lifecycle callbacks**, they are defined as public methods on the entity classes and
   they are called when the events are triggered;
-* **Lifecycle listeners and subscribers**, they are classes with callback
+* **Lifecycle listeners**, they are classes with callback
   methods for one or more events and they are called for all entities;
 * **Entity listeners**, they are similar to lifecycle listeners, but they are
   called only for the entities of a certain class.
@@ -25,7 +25,7 @@ These are the **drawbacks and advantages** of each one:
 * Callbacks have better performance because they only apply to a single entity
   class, but you can't reuse the logic for different entities and they don't
   have access to :doc:`Symfony services </service_container>`;
-* Lifecycle listeners and subscribers can reuse logic among different entities
+* Lifecycle listeners can reuse logic among different entities
   and can access Symfony services but their performance is worse because they
   are called for all entities;
 * Entity listeners have the same advantages of lifecycle listeners and they have
@@ -37,7 +37,7 @@ to learn everything about them.
 
 .. seealso::
 
-    This article covers listeners and subscribers for Doctrine ORM. If you are
+    This article covers listeners for Doctrine ORM. If you are
     using ODM for MongoDB, read the `DoctrineMongoDBBundle documentation`_.
 
 Doctrine Lifecycle Callbacks
@@ -110,11 +110,6 @@ define a callback for the ``prePersist`` Doctrine event:
 Doctrine Lifecycle Listeners
 ----------------------------
 
-.. deprecated:: 6.3
-
-    Lifecycle subscribers are deprecated starting from Symfony 6.3 and will be
-    removed in Symfony 7.0. Use lifecycle listeners instead.
-
 Lifecycle listeners are defined as PHP classes that listen to a single Doctrine
 event on all the application entities. For example, suppose that you want to
 update some search index whenever a new entity is persisted in the database. To
@@ -201,7 +196,7 @@ listener in the Symfony application by creating a new service for it and
                         # this is the only required option for the lifecycle listener tag
                         event: 'postPersist'
 
-                        # listeners can define their priority in case multiple subscribers or listeners are associated
+                        # listeners can define their priority in case listeners are associated
                         # to the same event (default priority = 0; higher numbers = listener is run earlier)
                         priority: 500
 
@@ -219,7 +214,7 @@ listener in the Symfony application by creating a new service for it and
 
                 <!--
                     * 'event' is the only required option that defines the lifecycle listener
-                    * 'priority': used when multiple subscribers or listeners are associated to the same event
+                    * 'priority': used when multiple listeners are associated to the same event
                     *             (default priority = 0; higher numbers = listener is run earlier)
                     * 'connection': restricts the listener to a specific Doctrine connection
                 -->
@@ -248,7 +243,7 @@ listener in the Symfony application by creating a new service for it and
                     // this is the only required option for the lifecycle listener tag
                     'event' => 'postPersist',
 
-                    // listeners can define their priority in case multiple subscribers or listeners are associated
+                    // listeners can define their priority in case multiple listeners are associated
                     // to the same event (default priority = 0; higher numbers = listener is run earlier)
                     'priority' => 500,
 
@@ -262,12 +257,6 @@ listener in the Symfony application by creating a new service for it and
 
     The `AsDoctrineListener`_ attribute was introduced in DoctrineBundle 2.7.2.
 
-.. tip::
-
-    Symfony loads (and instantiates) Doctrine listeners only when the related
-    Doctrine event is actually fired; whereas Doctrine subscribers are always
-    loaded (and instantiated) by Symfony, making them less performant.
-
 .. tip::
 
     The value of the ``connection`` option can also be a
@@ -414,148 +403,6 @@ with the ``doctrine.orm.entity_listener`` tag as follows:
             ;
         };
 
-Doctrine Lifecycle Subscribers
-------------------------------
-
-Lifecycle subscribers are defined as PHP classes that implement the
-``Doctrine\Common\EventSubscriber`` interface and which listen to one or more
-Doctrine events on all the application entities. For example, suppose that you
-want to log all the database activity. To do so, define a subscriber for the
-``postPersist``, ``postRemove`` and ``postUpdate`` Doctrine events::
-
-    // src/EventListener/DatabaseActivitySubscriber.php
-    namespace App\EventListener;
-
-    use App\Entity\Product;
-    use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface;
-    use Doctrine\ORM\Event\PostPersistEventArgs;
-    use Doctrine\ORM\Event\PostRemoveEventArgs;
-    use Doctrine\ORM\Event\PostUpdateEventArgs;
-    use Doctrine\ORM\Events;
-
-    class DatabaseActivitySubscriber implements EventSubscriberInterface
-    {
-        // this method can only return the event names; you cannot define a
-        // custom method name to execute when each event triggers
-        public function getSubscribedEvents(): array
-        {
-            return [
-                Events::postPersist,
-                Events::postRemove,
-                Events::postUpdate,
-            ];
-        }
-
-        // callback methods must be called exactly like the events they listen to;
-        // they receive an argument of type Post*EventArgs, which gives you access
-        // to both the entity object of the event and the entity manager itself
-        public function postPersist(PostPersistEventArgs $args): void
-        {
-            $this->logActivity('persist', $args->getObject());
-        }
-
-        public function postRemove(PostRemoveEventArgs $args): void
-        {
-            $this->logActivity('remove', $args->getObject());
-        }
-
-        public function postUpdate(PostUpdateEventArgs $args): void
-        {
-            $this->logActivity('update', $args->getObject());
-        }
-
-        private function logActivity(string $action, mixed $entity): void
-        {
-            // if this subscriber only applies to certain entity types,
-            // add some code to check the entity type as early as possible
-            if (!$entity instanceof Product) {
-                return;
-            }
-
-            // ... get the entity information and log it somehow
-        }
-    }
-
-.. note::
-
-    In previous Doctrine versions, instead of ``Post*EventArgs`` classes, you had
-    to use ``LifecycleEventArgs``, which was deprecated in Doctrine ORM 2.14.
-
-If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`
-and DoctrineBundle 2.1 (released May 25, 2020) or newer, this example will already
-work! Otherwise, :ref:`create a service <service-container-creating-service>` for this
-subscriber and :doc:`tag it </service_container/tags>` with ``doctrine.event_subscriber``.
-
-If you need to configure some option of the subscriber (e.g. its priority or
-Doctrine connection to use) you must do that in the manual service configuration:
-
-.. configuration-block::
-
-    .. code-block:: yaml
-
-        # config/services.yaml
-        services:
-            # ...
-
-            App\EventListener\DatabaseActivitySubscriber:
-                tags:
-                    - name: 'doctrine.event_subscriber'
-
-                      # subscribers can define their priority in case multiple subscribers or listeners are associated
-                      # to the same event (default priority = 0; higher numbers = listener is run earlier)
-                      priority: 500
-
-                      # you can also restrict listeners to a specific Doctrine connection
-                      connection: 'default'
-
-    .. code-block:: xml
-
-        <!-- config/services.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <container xmlns="http://symfony.com/schema/dic/services"
-            xmlns:doctrine="http://symfony.com/schema/dic/doctrine">
-            <services>
-                <!-- ... -->
-
-                <!--
-                    * 'priority': used when multiple subscribers or listeners are associated to the same event
-                    *             (default priority = 0; higher numbers = listener is run earlier)
-                    * 'connection': restricts the listener to a specific Doctrine connection
-                -->
-                <service id="App\EventListener\DatabaseActivitySubscriber">
-                    <tag name="doctrine.event_subscriber" priority="500" connection="default"/>
-                </service>
-            </services>
-        </container>
-
-    .. code-block:: php
-
-        // config/services.php
-        namespace Symfony\Component\DependencyInjection\Loader\Configurator;
-
-        use App\EventListener\DatabaseActivitySubscriber;
-
-        return static function (ContainerConfigurator $container): void {
-            $services = $container->services();
-
-            $services->set(DatabaseActivitySubscriber::class)
-                ->tag('doctrine.event_subscriber'[
-                    // subscribers can define their priority in case multiple subscribers or listeners are associated
-                    // to the same event (default priority = 0; higher numbers = listener is run earlier)
-                    'priority' => 500,
-
-                    // you can also restrict listeners to a specific Doctrine connection
-                    'connection' => 'default',
-                ])
-            ;
-        };
-
-.. tip::
-
-    Symfony loads (and instantiates) Doctrine subscribers whenever the
-    application executes; whereas Doctrine listeners are only loaded when the
-    related event is actually fired, making them more performant.
-
 .. _`Doctrine`: https://www.doctrine-project.org/
 .. _`lifecycle events`: https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/events.html#lifecycle-events
 .. _`official docs about Doctrine events`: https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/events.html
diff --git a/mailer.rst b/mailer.rst
index 8dc952f2fb9..22807ed3533 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -581,12 +581,6 @@ Alternatively you can attach contents from a stream by passing it directly to th
         ->addPart(new DataPart(fopen('/path/to/documents/contract.doc', 'r')))
     ;
 
-.. deprecated:: 6.2
-
-    In Symfony versions previous to 6.2, the methods ``attachFromPath()`` and
-    ``attach()`` could be used to add attachments. These methods have been
-    deprecated and replaced with ``addPart()``.
-
 Embedding Images
 ~~~~~~~~~~~~~~~~
 
@@ -628,12 +622,6 @@ images inside the HTML contents::
 
     The support of embedded images as HTML backgrounds was introduced in Symfony 6.1.
 
-.. deprecated:: 6.2
-
-    In Symfony versions previous to 6.2, the methods ``embedFromPath()`` and
-    ``embed()`` could be used to embed images. These methods have been deprecated
-    and replaced with ``addPart()`` together with inline ``DataPart`` objects.
-
 .. _mailer-configure-email-globally:
 
 Configuring Emails Globally
@@ -1561,7 +1549,7 @@ Here's an example of making one available to download::
         {
             $message = (new DraftEmail())
                 ->html($this->renderView(/* ... */))
-                ->attach(/* ... */)
+                ->addPart(/* ... */)
             ;
 
             $response = new Response($message->toString());
diff --git a/messenger.rst b/messenger.rst
index c30e05c8836..b6ea33e8094 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -889,12 +889,6 @@ properties in the ``reset()`` method.
 If you don't want to reset the container, add the ``--no-reset`` option when
 running the ``messenger:consume`` command.
 
-.. deprecated:: 6.1
-
-    In Symfony versions previous to 6.1, the service container didn't reset
-    automatically between messages and you had to set the
-    ``framework.messenger.reset_on_message`` option to ``true``.
-
 .. _messenger-retries-failures:
 
 Retries & Failures
diff --git a/reference/attributes.rst b/reference/attributes.rst
index 761099a7356..6d0c4efa9ba 100644
--- a/reference/attributes.rst
+++ b/reference/attributes.rst
@@ -5,11 +5,6 @@ Attributes are the successor of annotations since PHP 8. Attributes are native
 to the language and Symfony takes full advantage of them across the framework
 and its different components.
 
-.. deprecated:: 6.4
-
-    Annotations across the framework are deprecated since Symfony 6.4, you must
-    only use attributes instead.
-
 Doctrine Bridge
 ~~~~~~~~~~~~~~~
 
diff --git a/reference/configuration/doctrine.rst b/reference/configuration/doctrine.rst
index b1f2139034a..e28c50978e1 100644
--- a/reference/configuration/doctrine.rst
+++ b/reference/configuration/doctrine.rst
@@ -270,13 +270,9 @@ you can control. The following configuration options exist for a mapping:
 ``type``
 ........
 
-One of ``annotation`` (for PHP annotations; it's the default value),
-``attribute`` (for PHP attributes), ``xml``, ``yml``, ``php`` or
-``staticphp``. This specifies which type of metadata type your mapping uses.
-
-.. deprecated:: 6.4
-
-    Annotations are deprecated since Symfony 6.4, use attributes instead.
+One of ``attribute`` (for PHP attributes; it's the default value),
+``xml``, ``yml``, ``php`` or ``staticphp``. This specifies which
+type of metadata type your mapping uses.
 
 See `Doctrine Metadata Drivers`_ for more information about this option.
 
diff --git a/reference/formats/expression_language.rst b/reference/formats/expression_language.rst
index f38c951e372..a561ed5ce6d 100644
--- a/reference/formats/expression_language.rst
+++ b/reference/formats/expression_language.rst
@@ -333,7 +333,7 @@ Array Operators
 * ``in`` (contain)
 * ``not in`` (does not contain)
 
-For example::
+These operators are using strict comparison. For example::
 
     class User
     {
diff --git a/reference/forms/types/options/date_widget_description.rst.inc b/reference/forms/types/options/date_widget_description.rst.inc
index 99573a2358a..956ad8c7148 100644
--- a/reference/forms/types/options/date_widget_description.rst.inc
+++ b/reference/forms/types/options/date_widget_description.rst.inc
@@ -10,8 +10,3 @@ following:
 
 * ``single_text``: renders a single input of type ``date``. User's input
   is validated based on the `format`_ option.
-
-.. deprecated:: 6.3
-
-    Not setting a value explicitly for this option is deprecated since Symfony 6.3
-    because the default value will change to ``single_text`` in Symfony 7.0.
diff --git a/serializer/custom_normalizer.rst b/serializer/custom_normalizer.rst
index 0ee272f0325..58e6ef2d075 100644
--- a/serializer/custom_normalizer.rst
+++ b/serializer/custom_normalizer.rst
@@ -58,15 +58,6 @@ normalization process::
         }
     }
 
-.. deprecated:: 6.4
-
-    Injecting an ``ObjectNormalizer`` in your custom normalizer is deprecated
-    since Symfony 6.4. Implement the
-    :class:`Symfony\\Component\\Serializer\\Normalizer\\NormalizerAwareInterface`
-    and use the
-    :class:`Symfony\\Component\\Serializer\\Normalizer\\NormalizerAwareTrait` instead
-    to inject the ``$normalizer`` property.
-
 Registering it in your Application
 ----------------------------------
 
diff --git a/service_container/service_decoration.rst b/service_container/service_decoration.rst
index 8a9ac1322f2..0262ae03e7e 100644
--- a/service_container/service_decoration.rst
+++ b/service_container/service_decoration.rst
@@ -211,12 +211,6 @@ automatically changed to ``'.inner'``):
                 ->args([service('.inner')]);
         };
 
-.. deprecated:: 6.3
-
-    The ``#[MapDecorated]`` attribute is deprecated since Symfony 6.3.
-    Instead, use the
-    :class:`#[AutowireDecorated] <Symfony\\Component\\DependencyInjection\\Attribute\\AutowireDecorated>` attribute.
-
 .. tip::
 
     The visibility of the decorated ``App\Mailer`` service (which is an alias

From bae960241c7f044659e3c503b79d63f85e8b960b Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Thu, 17 Aug 2023 12:47:16 +0200
Subject: [PATCH 029/747] clean up more legacy annotation config

---
 components/validator/resources.rst | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/components/validator/resources.rst b/components/validator/resources.rst
index 19b0c54b6ec..1b512942325 100644
--- a/components/validator/resources.rst
+++ b/components/validator/resources.rst
@@ -88,30 +88,24 @@ The AnnotationLoader
 
 At last, the component provides an
 :class:`Symfony\\Component\\Validator\\Mapping\\Loader\\AnnotationLoader` to get
-the metadata from the annotations of the class. Annotations are defined as ``@``
-prefixed classes included in doc block comments (``/** ... */``). For example::
+the metadata from the attributes of the class::
 
     use Symfony\Component\Validator\Constraints as Assert;
     // ...
 
     class User
     {
-        /**
-         * @Assert\NotBlank
-         */
+        #[Assert\NotBlank]
         protected string $name;
     }
 
 To enable the annotation loader, call the
-:method:`Symfony\\Component\\Validator\\ValidatorBuilder::enableAnnotationMapping` method.
-If you use annotations instead of attributes, it's also required to call
-``addDefaultDoctrineAnnotationReader()`` to use Doctrine's annotation reader::
+:method:`Symfony\\Component\\Validator\\ValidatorBuilder::enableAnnotationMapping` method::
 
     use Symfony\Component\Validator\Validation;
 
     $validator = Validation::createValidatorBuilder()
         ->enableAnnotationMapping()
-        ->addDefaultDoctrineAnnotationReader() // add this only when using annotations
         ->getValidator();
 
 To disable the annotation loader after it was enabled, call
@@ -133,7 +127,6 @@ multiple mappings::
 
     $validator = Validation::createValidatorBuilder()
         ->enableAnnotationMapping(true)
-        ->addDefaultDoctrineAnnotationReader()
         ->addMethodMapping('loadValidatorMetadata')
         ->addXmlMapping('validator/validation.xml')
         ->getValidator();

From 4fbda5d91644e72c2e164b1eaeea6028e0b10765 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 5 Sep 2023 11:11:29 +0200
Subject: [PATCH 030/747] [Workflow] Remove `GuardEvent::getContext()` method
 without replacement

---
 workflow.rst | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/workflow.rst b/workflow.rst
index 88021884130..2e17b40794c 100644
--- a/workflow.rst
+++ b/workflow.rst
@@ -463,21 +463,6 @@ order:
 
         $workflow->apply($subject, $transitionName, [Workflow::DISABLE_ANNOUNCE_EVENT => true]);
 
-The context is accessible in all events except for the ``workflow.guard`` events::
-
-    // $context must be an array
-    $context = ['context_key' => 'context_value'];
-    $workflow->apply($subject, $transitionName, $context);
-
-    // in an event listener (workflow.guard events)
-    $context = $event->getContext(); // returns ['context']
-
-.. deprecated:: 6.4
-
-    Gathering events context is deprecated since Symfony 6.4 and the
-    :method:`Symfony\\Component\\Workflow\\Event::getContext` method will be
-    removed in Symfony 7.0.
-
 .. note::
 
     The leaving and entering events are triggered even for transitions that stay

From d7717fb4ea37ee57c3f4b5b56051c5fa82fb830f Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 5 Sep 2023 11:15:20 +0200
Subject: [PATCH 031/747] Remove mentions of AnnotationLoader

---
 _includes/_annotation_loader_tip.rst.inc | 19 ----------
 components/validator/resources.rst       | 46 ------------------------
 reference/configuration/framework.rst    | 24 -------------
 3 files changed, 89 deletions(-)
 delete mode 100644 _includes/_annotation_loader_tip.rst.inc

diff --git a/_includes/_annotation_loader_tip.rst.inc b/_includes/_annotation_loader_tip.rst.inc
deleted file mode 100644
index 0f4267b07f5..00000000000
--- a/_includes/_annotation_loader_tip.rst.inc
+++ /dev/null
@@ -1,19 +0,0 @@
-.. note::
-
-    In order to use the annotation loader, you should have installed the
-    ``doctrine/annotations`` and ``doctrine/cache`` packages with Composer.
-
-.. tip::
-
-    Annotation classes aren't loaded automatically, so you must load them
-    using a class loader like this::
-
-        use Composer\Autoload\ClassLoader;
-        use Doctrine\Common\Annotations\AnnotationRegistry;
-
-        /** @var ClassLoader $loader */
-        $loader = require __DIR__.'/../vendor/autoload.php';
-
-        AnnotationRegistry::registerLoader([$loader, 'loadClass']);
-
-        return $loader;
diff --git a/components/validator/resources.rst b/components/validator/resources.rst
index dd218a26a12..d9d3543a641 100644
--- a/components/validator/resources.rst
+++ b/components/validator/resources.rst
@@ -83,52 +83,6 @@ configure the locations of these files::
     :method:`Symfony\\Component\\Validator\\ValidatorBuilder::addXmlMappings`
     to configure an array of file paths.
 
-The AnnotationLoader
---------------------
-
-.. deprecated:: 6.4
-
-    The :class:`Symfony\\Component\\Validator\\Mapping\\Loader\\AnnotationLoader`
-    is deprecated since Symfony 6.4, use the
-    :class:`Symfony\\Component\\Validator\\Mapping\\Loader\\AttributeLoader`
-    instead.
-
-The component provides an
-:class:`Symfony\\Component\\Validator\\Mapping\\Loader\\AnnotationLoader` to get
-the metadata from the attributes of the class::
-
-    use Symfony\Component\Validator\Constraints as Assert;
-    // ...
-
-    class User
-    {
-        #[Assert\NotBlank]
-        protected string $name;
-    }
-
-To enable the annotation loader, call the
-:method:`Symfony\\Component\\Validator\\ValidatorBuilder::enableAnnotationMapping` method::
-
-    use Symfony\Component\Validator\Validation;
-
-    $validator = Validation::createValidatorBuilder()
-        ->enableAnnotationMapping()
-        ->getValidator();
-
-To disable the annotation loader after it was enabled, call
-:method:`Symfony\\Component\\Validator\\ValidatorBuilder::disableAnnotationMapping`.
-
-.. deprecated:: 6.4
-
-    The :method:`Symfony\\Component\\Validator\\ValidatorBuilder::enableAnnotationMapping`
-    and :method:`Symfony\\Component\\Validator\\ValidatorBuilder::disableAnnotationMapping`
-    methods are deprecated since Symfony 6.4, use the
-    :method:`Symfony\\Component\\Validator\\ValidatorBuilder::enableAttributeMapping`
-    and :method:`Symfony\\Component\\Validator\\ValidatorBuilder::disableAttributeMapping`
-    methods instead.
-
-.. include:: /_includes/_annotation_loader_tip.rst.inc
-
 The AttributeLoader
 -------------------
 
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index efa028b0824..a498328e9fe 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -2701,18 +2701,6 @@ settings is configured.
 
 .. _reference-validation-enable_annotations:
 
-enable_annotations
-..................
-
-**type**: ``boolean`` **default**: ``true``
-
-If this option is enabled, validation constraints can be defined using annotations or `PHP attributes`_.
-
-.. deprecated:: 6.4
-
-    This option is deprecated since Symfony 6.4, use the ``enable_attributes``
-    option instead.
-
 enable_attributes
 .................
 
@@ -2899,18 +2887,6 @@ Whether to enable the ``serializer`` service or not in the service container.
 
 .. _reference-serializer-enable_annotations:
 
-enable_annotations
-..................
-
-**type**: ``boolean`` **default**: ``true``
-
-If this option is enabled, serialization groups can be defined using annotations or attributes.
-
-.. deprecated:: 6.4
-
-    This option is deprecated since Symfony 6.4, use the ``enable_attributes``
-    option instead.
-
 enable_attributes
 .................
 

From 73121fbd0e59644259c1d50dd3c59aeab4cdbb47 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 5 Sep 2023 13:30:58 +0200
Subject: [PATCH 032/747] Remove a versionadded directive

---
 routing.rst | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/routing.rst b/routing.rst
index 11aea4039b3..6a6d2095e23 100644
--- a/routing.rst
+++ b/routing.rst
@@ -2258,11 +2258,6 @@ that defines only one route. Consider the following class::
 
 Symfony will add a route alias named ``App\Controller\MainController::homepage``.
 
-.. versionadded:: 6.4
-
-    The automatic declaration of route aliases based on FQCNs was introduced in
-    Symfony 6.4.
-
 Generating URLs in Controllers
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From 79da0629e6ea7fdb1b747e3b55da4f1f10a6a50e Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 22 Sep 2023 11:02:26 +0200
Subject: [PATCH 033/747] Remove a versionadded directive

---
 console.rst | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/console.rst b/console.rst
index 86f05625dd6..2aafad3f602 100644
--- a/console.rst
+++ b/console.rst
@@ -582,11 +582,6 @@ even the color mode being used. You have access to such information thanks to th
     // changes the color mode
     $colorMode = $terminal->setColorMode(AnsiColorMode::Ansi24);
 
-.. versionadded:: 6.2
-
-    The support for setting and getting the current color mode was introduced
-    in Symfony 6.2.
-
 Logging Command Errors
 ----------------------
 

From b2c73abc2cdcac9030f4fd9d0582f9649bbd5cb2 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 4 Oct 2023 09:10:49 +0200
Subject: [PATCH 034/747] Remove an unneeded versionadded directive

---
 routing.rst | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/routing.rst b/routing.rst
index e109170e294..fb5931cc517 100644
--- a/routing.rst
+++ b/routing.rst
@@ -2724,12 +2724,6 @@ service, which you can inject in your services or controllers::
         }
     }
 
-.. versionadded:: 6.4
-
-    The namespace of the ``UriSigner`` class changed in Symfony 6.4 from
-    ``Symfony\Component\HttpKernel\UriSigner`` to
-    ``Symfony\Component\HttpFoundation\UriSigner``.
-
 Troubleshooting
 ---------------
 

From a45366817bd43f44b7bd9e6e45d41921df943731 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 4 Oct 2023 13:38:47 +0200
Subject: [PATCH 035/747] [RateLimiter] Remove deprecations

---
 rate_limiter.rst | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/rate_limiter.rst b/rate_limiter.rst
index 06c888b480b..1fe86ef020a 100644
--- a/rate_limiter.rst
+++ b/rate_limiter.rst
@@ -375,14 +375,6 @@ the :class:`Symfony\\Component\\RateLimiter\\Reservation` object returned by the
     The :method:`Symfony\\Component\\RateLimiter\\Policy\\SlidingWindow::calculateTimeForTokens`
     method was introduced in Symfony 6.4.
 
-.. deprecated:: 6.4
-
-    The :method:`Symfony\\Component\\RateLimiter\\Policy\\SlidingWindow::getRetryAfter`
-    method is deprecated since Symfony 6.4. Prior to this version, the
-    ``getRetryAfter()`` method must be used instead of the
-    :method:`Symfony\\Component\\RateLimiter\\Policy\\SlidingWindow::calculateTimeForTokens`
-    method.
-
 .. _rate-limiter-storage:
 
 Storing Rate Limiter State

From 83162e3f96cc997d31b7e695d0e2143b33af232f Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 6 Oct 2023 16:18:57 +0200
Subject: [PATCH 036/747] Remove an unneeded reference to a not recommended
 feature

---
 security.rst | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/security.rst b/security.rst
index 301371bede9..7285a6b77b4 100644
--- a/security.rst
+++ b/security.rst
@@ -2678,15 +2678,6 @@ like this:
   :doc:`impersonating </security/impersonating_user>` another user in this
   session, this attribute will match.
 
-.. note::
-
-    All logged in users also have an attribute called ``IS_AUTHENTICATED_REMEMBERED``,
-    even if the application doesn't use the Remember Me feature. This attribute
-    exists for backward-compatibility reasons with Symfony versions prior to 6.4.
-
-    This attribute behaves the same as ``IS_AUTHENTICATED``. That's why in modern
-    Symfony applications it's recommended to no longer use ``IS_AUTHENTICATED_REMEMBERED``.
-
 .. _user_session_refresh:
 
 Understanding how Users are Refreshed from the Session

From bbd1d8e092c672be67ea75f3f346cd126c5a9de4 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 16 Oct 2023 10:47:57 +0200
Subject: [PATCH 037/747] Remove all 6.x `versionadded` on 7.0

---
 .doctor-rst.yaml                              |  8 +-
 bundles.rst                                   |  5 --
 bundles/configuration.rst                     |  4 -
 bundles/extension.rst                         |  4 -
 bundles/prepend_extension.rst                 |  4 -
 cache.rst                                     | 12 ---
 components/browser_kit.rst                    |  8 --
 components/cache/adapters/redis_adapter.rst   |  8 --
 components/clock.rst                          | 32 -------
 components/config/definition.rst              |  5 --
 components/console/events.rst                 | 15 ----
 .../console/helpers/formatterhelper.rst       |  4 -
 components/console/helpers/progressbar.rst    |  8 --
 components/console/helpers/table.rst          |  4 -
 components/css_selector.rst                   |  4 -
 .../dependency_injection/compilation.rst      |  4 -
 components/dom_crawler.rst                    | 14 ---
 components/expression_language.rst            |  4 -
 components/finder.rst                         |  5 --
 components/http_foundation.rst                | 34 +------
 components/http_kernel.rst                    | 11 ---
 components/intl.rst                           | 12 ---
 components/lock.rst                           |  9 --
 components/options_resolver.rst               |  4 -
 components/phpunit_bridge.rst                 | 16 ----
 components/process.rst                        |  4 -
 components/property_access.rst                |  9 --
 components/property_info.rst                  |  6 --
 components/serializer.rst                     | 26 ------
 components/string.rst                         |  8 --
 components/uid.rst                            | 20 -----
 components/validator/resources.rst            |  5 --
 components/var_dumper.rst                     |  4 -
 components/var_exporter.rst                   | 13 ---
 components/yaml.rst                           |  8 --
 configuration.rst                             | 20 -----
 configuration/env_var_processors.rst          | 12 ---
 configuration/micro_kernel_trait.rst          |  8 --
 console.rst                                   | 12 ---
 console/coloring.rst                          |  4 -
 console/input.rst                             |  6 --
 console/style.rst                             |  8 --
 contributing/documentation/format.rst         | 20 ++---
 controller.rst                                | 32 -------
 controller/value_resolver.rst                 | 42 ---------
 doctrine.rst                                  |  9 --
 form/unit_testing.rst                         |  5 --
 frontend/asset_mapper.rst                     | 21 -----
 html_sanitizer.rst                            |  4 -
 http_cache.rst                                |  4 -
 http_cache/esi.rst                            |  4 -
 http_client.rst                               | 46 ----------
 lock.rst                                      |  5 --
 mailer.rst                                    | 79 -----------------
 messenger.rst                                 | 88 -------------------
 notifier.rst                                  | 57 ------------
 performance.rst                               |  4 -
 profiler.rst                                  |  8 --
 rate_limiter.rst                              | 10 ---
 reference/configuration/debug.rst             |  4 -
 reference/configuration/framework.rst         | 48 ----------
 reference/configuration/kernel.rst            |  5 --
 reference/configuration/security.rst          | 16 ----
 reference/configuration/twig.rst              | 13 ---
 reference/constraints/Cascade.rst             |  4 -
 reference/constraints/Choice.rst              |  4 -
 reference/constraints/Email.rst               |  4 -
 reference/constraints/Expression.rst          | 12 ---
 reference/constraints/File.rst                | 16 ----
 reference/constraints/Length.rst              | 16 ----
 .../constraints/NoSuspiciousCharacters.rst    |  4 -
 reference/constraints/PasswordStrength.rst    |  4 -
 reference/constraints/Regex.rst               |  4 -
 reference/constraints/Time.rst                |  4 -
 reference/constraints/Type.rst                |  4 -
 reference/constraints/Unique.rst              |  4 -
 reference/constraints/UniqueEntity.rst        |  5 --
 reference/constraints/Uuid.rst                |  9 --
 reference/constraints/When.rst                |  8 --
 reference/dic_tags.rst                        |  7 --
 reference/formats/expression_language.rst     | 18 ----
 reference/formats/yaml.rst                    |  4 -
 reference/forms/types/collection.rst          |  4 -
 reference/forms/types/enum.rst                |  4 -
 reference/forms/types/number.rst              |  4 -
 .../forms/types/options/choice_label.rst.inc  |  6 --
 .../duplicate_preferred_choices.rst.inc       |  4 -
 reference/forms/types/options/help.rst.inc    |  5 --
 .../types/options/placeholder_attr.rst.inc    |  4 -
 .../forms/types/options/sanitize_html.rst.inc |  4 -
 .../forms/types/options/sanitizer.rst.inc     |  4 -
 reference/forms/types/password.rst            |  4 -
 reference/twig_reference.rst                  | 12 ---
 routing.rst                                   | 38 --------
 routing/custom_route_loader.rst               |  9 --
 security.rst                                  | 60 -------------
 security/access_control.rst                   |  8 --
 security/access_token.rst                     |  8 --
 security/expressions.rst                      |  4 -
 security/impersonating_user.rst               |  4 -
 security/login_link.rst                       |  4 -
 security/remember_me.rst                      |  4 -
 security/user_checkers.rst                    |  4 -
 security/voters.rst                           |  4 -
 serializer.rst                                | 26 ------
 serializer/custom_context_builders.rst        |  4 -
 service_container.rst                         | 14 ---
 service_container/alias_private.rst           |  4 -
 service_container/autowiring.rst              | 18 ----
 service_container/debug.rst                   |  6 +-
 service_container/expression_language.rst     |  8 --
 service_container/factories.rst               |  8 --
 service_container/lazy_services.rst           | 10 ---
 service_container/service_decoration.rst      |  4 -
 .../service_subscribers_locators.rst          | 20 -----
 service_container/tags.rst                    | 13 ---
 templates.rst                                 | 28 ------
 testing.rst                                   | 38 --------
 translation.rst                               | 29 ------
 validation.rst                                |  4 -
 validation/custom_constraint.rst              |  4 -
 workflow.rst                                  | 24 -----
 workflow/workflow-and-state-machine.rst       |  4 -
 123 files changed, 18 insertions(+), 1516 deletions(-)

diff --git a/.doctor-rst.yaml b/.doctor-rst.yaml
index ee1713d3100..f309ce1d49d 100644
--- a/.doctor-rst.yaml
+++ b/.doctor-rst.yaml
@@ -68,16 +68,16 @@ rules:
 
     #   master
     versionadded_directive_major_version:
-        major_version: 6
+        major_version: 7
 
     versionadded_directive_min_version:
-        min_version: '6.0'
+        min_version: '7.0'
 
     deprecated_directive_major_version:
-        major_version: 6
+        major_version: 7
 
     deprecated_directive_min_version:
-        min_version: '6.0'
+        min_version: '7.0'
 
 exclude_rule_for_file:
     - path: configuration/multiple_kernels.rst
diff --git a/bundles.rst b/bundles.rst
index 19dd8c31aa8..50ffc39d156 100644
--- a/bundles.rst
+++ b/bundles.rst
@@ -56,11 +56,6 @@ Start by creating a new class called ``AcmeTestBundle``::
     {
     }
 
-.. versionadded:: 6.1
-
-    The :class:`Symfony\\Component\\HttpKernel\\Bundle\\AbstractBundle` was
-    introduced in Symfony 6.1.
-
 .. caution::
 
     If your bundle must be compatible with previous Symfony versions you have to
diff --git a/bundles/configuration.rst b/bundles/configuration.rst
index 4a2224429ed..a6a21023de6 100644
--- a/bundles/configuration.rst
+++ b/bundles/configuration.rst
@@ -320,10 +320,6 @@ In your extension, you can load this and dynamically set its arguments::
 Using the AbstractBundle Class
 ------------------------------
 
-.. versionadded:: 6.1
-
-    The ``AbstractBundle`` class was introduced in Symfony 6.1.
-
 As an alternative, instead of creating an extension and configuration class as
 shown in the previous section, you can also extend
 :class:`Symfony\\Component\\HttpKernel\\Bundle\\AbstractBundle` to add this
diff --git a/bundles/extension.rst b/bundles/extension.rst
index ff873f2ab14..3c660251403 100644
--- a/bundles/extension.rst
+++ b/bundles/extension.rst
@@ -111,10 +111,6 @@ To read more about it, see the ":doc:`/bundles/configuration`" article.
 Loading Services directly in your Bundle class
 ----------------------------------------------
 
-.. versionadded:: 6.1
-
-    The ``AbstractBundle`` class was introduced in Symfony 6.1.
-
 Alternatively, you can define and load services configuration directly in a
 bundle class instead of creating a specific ``Extension`` class. You can do
 this by extending from :class:`Symfony\\Component\\HttpKernel\\Bundle\\AbstractBundle`
diff --git a/bundles/prepend_extension.rst b/bundles/prepend_extension.rst
index fcad249124e..bed3d06da43 100644
--- a/bundles/prepend_extension.rst
+++ b/bundles/prepend_extension.rst
@@ -154,10 +154,6 @@ registered and the ``entity_manager_name`` setting for ``acme_hello`` is set to
 Prepending Extension in the Bundle Class
 ----------------------------------------
 
-.. versionadded:: 6.1
-
-    The ``AbstractBundle`` class was introduced in Symfony 6.1.
-
 You can also append or prepend extension configuration directly in your
 Bundle class if you extend from the :class:`Symfony\\Component\\HttpKernel\\Bundle\\AbstractBundle`
 class and define the :method:`Symfony\\Component\\HttpKernel\\Bundle\\AbstractBundle::prependExtension`
diff --git a/cache.rst b/cache.rst
index 7bf72bf2608..3d247c4a1bb 100644
--- a/cache.rst
+++ b/cache.rst
@@ -745,20 +745,12 @@ Clear all cache pools:
 
     $ php bin/console cache:pool:clear --all
 
-.. versionadded:: 6.3
-
-    The ``--all`` option was introduced in Symfony 6.3.
-
 Clear all cache pools except some:
 
 .. code-block:: terminal
 
     $ php bin/console cache:pool:clear --all --exclude=my_cache_pool --exclude=another_cache_pool
 
-.. versionadded:: 6.4
-
-    The ``--exclude`` option was introduced in Symfony 6.4.
-
 Clear all caches everywhere:
 
 .. code-block:: terminal
@@ -767,10 +759,6 @@ Clear all caches everywhere:
 
 Clear cache by tag(s):
 
-.. versionadded:: 6.1
-
-    The ``cache:pool:invalidate-tags`` command was introduced in Symfony 6.1.
-
 .. code-block:: terminal
 
     # invalidate tag1 from all taggable pools
diff --git a/components/browser_kit.rst b/components/browser_kit.rst
index c744837d7b1..bcb8f7b3c8e 100644
--- a/components/browser_kit.rst
+++ b/components/browser_kit.rst
@@ -130,10 +130,6 @@ on a link::
     // ... and `clickLink()`
     $crawler = $client->clickLink('Go elsewhere...', ['X-Custom-Header' => 'Some data']);
 
-.. versionadded:: 6.4
-
-    The ``serverParameters`` parameter was introduced in Symfony 6.4.
-
 Submitting Forms
 ~~~~~~~~~~~~~~~~
 
@@ -403,10 +399,6 @@ to call ``json_decode()`` explicitly::
     $response = $browser->getResponse()->toArray();
     // $response is a PHP array of the decoded JSON contents
 
-.. versionadded:: 6.1
-
-    The ``toArray()`` method was introduced in Symfony 6.1.
-
 Learn more
 ----------
 
diff --git a/components/cache/adapters/redis_adapter.rst b/components/cache/adapters/redis_adapter.rst
index 02523dd283e..a25b1a510ed 100644
--- a/components/cache/adapters/redis_adapter.rst
+++ b/components/cache/adapters/redis_adapter.rst
@@ -41,10 +41,6 @@ as the second and third parameters::
         $defaultLifetime = 0
     );
 
-.. versionadded:: 6.3
-
-    Support for `Relay`_ was introduced in Symfony 6.3.
-
 Configure the Connection
 ------------------------
 
@@ -163,10 +159,6 @@ array of ``key => value`` pairs representing option names and their respective v
 Available Options
 ~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.3
-
-    ``\Relay\Relay`` support was introduced in Symfony 6.3.
-
 ``class`` (type: ``string``, default: ``null``)
     Specifies the connection library to return, either ``\Redis``, ``\Relay\Relay`` or ``\Predis\Client``.
     If none is specified, fallback value is in following order, depending which one is available first:
diff --git a/components/clock.rst b/components/clock.rst
index f58124c70af..b803c78e29d 100644
--- a/components/clock.rst
+++ b/components/clock.rst
@@ -1,10 +1,6 @@
 The Clock Component
 ===================
 
-.. versionadded:: 6.2
-
-    The Clock component was introduced in Symfony 6.2
-
 The Clock component decouples applications from the system clock. This allows
 you to fix time to improve testability of time-sensitive logic.
 
@@ -79,16 +75,6 @@ When using the Clock component, you manipulate
 :class:`Symfony\\Component\\Clock\\DatePoint` instances. You can learn more
 about it in :ref:`the dedicated section <clock_date-point>`.
 
-.. versionadded:: 6.3
-
-    The :class:`Symfony\\Component\\Clock\\Clock` class and ``now()`` function
-    were introduced in Symfony 6.3.
-
-.. versionadded:: 6.4
-
-    The ``modifier`` argument of the ``now()`` function was introduced in
-    Symfony 6.4.
-
 Available Clocks Implementations
 --------------------------------
 
@@ -208,10 +194,6 @@ you can set the current time arbitrarily without having to change your service c
 This will help you test every case of your method without the need of actually
 being in a month or another.
 
-.. versionadded:: 6.3
-
-    The :class:`Symfony\\Component\\Clock\\ClockAwareTrait` was introduced in Symfony 6.3.
-
 .. _clock_date-point:
 
 The ``DatePoint`` Class
@@ -253,11 +235,6 @@ The constructor also allows setting a timezone or custom referenced date::
     error handling across versions of PHP, thanks to polyfilling `PHP 8.3's behavior`_
     on the topic.
 
-.. versionadded:: 6.4
-
-    The :class:`Symfony\\Component\\Clock\\DatePoint` class was introduced
-    in Symfony 6.4.
-
 .. _clock_writing-tests:
 
 Writing Time-Sensitive Tests
@@ -314,10 +291,6 @@ By combining the :class:`Symfony\\Component\\Clock\\ClockAwareTrait` and
 :class:`Symfony\\Component\\Clock\\Test\\ClockSensitiveTrait`, you have full
 control on your time-sensitive code's behavior.
 
-.. versionadded:: 6.3
-
-    The :class:`Symfony\\Component\\Clock\\Test\\ClockSensitiveTrait` was introduced in Symfony 6.3.
-
 Exceptions Management
 ---------------------
 
@@ -338,11 +311,6 @@ These exceptions are available starting from PHP 8.3. However, thanks to the
 `symfony/polyfill-php83`_ dependency required by the Clock component, you can
 use them even if your project doesn't use PHP 8.3 yet.
 
-.. versionadded:: 6.4
-
-    The support for ``DateMalformedStringException`` and
-    ``DateInvalidTimeZoneException`` was introduced in Symfony 6.4.
-
 .. _`PSR-20`: https://www.php-fig.org/psr/psr-20/
 .. _`accepted by the DateTime constructor`: https://www.php.net/manual/en/datetime.formats.php
 .. _`PHP DateTime exceptions`: https://wiki.php.net/rfc/datetime-exceptions
diff --git a/components/config/definition.rst b/components/config/definition.rst
index 9c90304c578..63ebcd7cc72 100644
--- a/components/config/definition.rst
+++ b/components/config/definition.rst
@@ -171,11 +171,6 @@ The configuration can now be written like this::
         ->end()
     ;
 
-.. versionadded:: 6.3
-
-    The support of enum values in ``enumNode()`` was introduced
-    in Symfony 6.3.
-
 Array Nodes
 ~~~~~~~~~~~
 
diff --git a/components/console/events.rst b/components/console/events.rst
index 6356816a9b2..1476a83f37d 100644
--- a/components/console/events.rst
+++ b/components/console/events.rst
@@ -156,11 +156,6 @@ Listeners receive a
     a signal. You can learn more about signals in the
     :ref:`the dedicated section <console-events_signal>`.
 
-    .. versionadded:: 6.4
-
-        Dispatching the ``ConsoleEvents::TERMINATE`` event on exit
-        signal was introduced in Symfony 6.4.
-
 .. _console-events_signal:
 
 The ``ConsoleEvents::SIGNAL`` Event
@@ -207,11 +202,6 @@ method::
         $event->abortExit();
     });
 
-.. versionadded:: 6.3
-
-    The ``setExitCode()``, ``getExitCode()`` and ``abortExit()`` methods were introduced
-    in Symfony 6.3.
-
 .. tip::
 
     All the available signals (``SIGINT``, ``SIGQUIT``, etc.) are defined as
@@ -262,11 +252,6 @@ handle all signals e.g. to do some tasks before terminating the command.
     :method:`Symfony\\Component\\Console\\SignalRegistry\\SignalMap::getSignalName`
     method.
 
-    .. versionadded:: 6.4
-
-        The :class:`Symfony\\Component\\Console\\SignalRegistry\\SignalMap` class was
-        introduced in Symfony 6.4.
-
 .. _`reserved exit codes`: https://www.tldp.org/LDP/abs/html/exitcodes.html
 .. _`Signals`: https://en.wikipedia.org/wiki/Signal_(IPC)
 .. _`constants of the PCNTL PHP extension`: https://www.php.net/manual/en/pcntl.constants.php
diff --git a/components/console/helpers/formatterhelper.rst b/components/console/helpers/formatterhelper.rst
index 061b7616c8d..3beb4204622 100644
--- a/components/console/helpers/formatterhelper.rst
+++ b/components/console/helpers/formatterhelper.rst
@@ -132,7 +132,3 @@ precision (default ``1``) of the result::
     $formatter->truncate(125);       // 2 mins
     $formatter->truncate(125, 2);    // 2 mins, 5 secs
     $formatter->truncate(172799, 4); // 1 day, 23 hrs, 59 mins, 59 secs
-
-.. versionadded:: 6.4
-
-    The support for exact times were introduced in Symfony 6.4.
diff --git a/components/console/helpers/progressbar.rst b/components/console/helpers/progressbar.rst
index 58f1fba37ff..a501d39fa14 100644
--- a/components/console/helpers/progressbar.rst
+++ b/components/console/helpers/progressbar.rst
@@ -69,10 +69,6 @@ that starting point::
     // displays the progress bar starting at 25 completed units
     $progressBar->start(null, 25);
 
-.. versionadded:: 6.2
-
-    The option to start a progress bar at a certain point was introduced in Symfony 6.2.
-
 .. tip::
 
     If your platform doesn't support ANSI codes, updates to the progress
@@ -375,10 +371,6 @@ with the ``setPlaceholderFormatter`` method::
         return $progressBar->getMaxSteps() - $progressBar->getProgress();
     });
 
-.. versionadded:: 6.3
-
-    The ``setPlaceholderFormatter()`` method was introduced in Symfony 6.3.
-
 Custom Messages
 ~~~~~~~~~~~~~~~
 
diff --git a/components/console/helpers/table.rst b/components/console/helpers/table.rst
index fcc52e0e7a4..6d86cbc6130 100644
--- a/components/console/helpers/table.rst
+++ b/components/console/helpers/table.rst
@@ -175,10 +175,6 @@ The output of this command will be:
     | Author: Charles Dickens      |
     +------------------------------+
 
-.. versionadded:: 6.1
-
-    Support for vertical rendering was introduced in Symfony 6.1.
-
 The table style can be changed to any built-in styles via
 :method:`Symfony\\Component\\Console\\Helper\\Table::setStyle`::
 
diff --git a/components/css_selector.rst b/components/css_selector.rst
index 94561cec9bd..c09f80a3cf4 100644
--- a/components/css_selector.rst
+++ b/components/css_selector.rst
@@ -94,10 +94,6 @@ Pseudo-classes are partially supported:
   ``li:first-of-type``) but not with the ``*`` selector).
 * Supported: ``*:only-of-type``, ``*:scope``.
 
-.. versionadded:: 6.3
-
-    The support for ``*:scope`` was introduced in Symfony 6.3.
-
 Learn more
 ----------
 
diff --git a/components/dependency_injection/compilation.rst b/components/dependency_injection/compilation.rst
index 8fe7b0242e5..3787c686982 100644
--- a/components/dependency_injection/compilation.rst
+++ b/components/dependency_injection/compilation.rst
@@ -278,10 +278,6 @@ The parameter being deprecated must be set before being declared as deprecated.
 Otherwise a :class:`Symfony\\Component\\DependencyInjection\\Exception\\ParameterNotFoundException`
 exception will be thrown.
 
-.. versionadded:: 6.3
-
-    The ``ContainerBuilder::deprecateParameter()`` method was introduced in Symfony 6.3.
-
 .. note::
 
     Just registering an extension with the container is not enough to get
diff --git a/components/dom_crawler.rst b/components/dom_crawler.rst
index 4440a35f0ea..ac859efac91 100644
--- a/components/dom_crawler.rst
+++ b/components/dom_crawler.rst
@@ -229,11 +229,6 @@ Access the value of the first node of the current selection::
     // but you can get the unchanged text by passing FALSE as argument
     $text = $crawler->filterXPath('//body/p')->innerText(false);
 
-.. versionadded:: 6.3
-
-    The removal of whitespace characters by default in ``innerText()`` was
-    introduced in Symfony 6.3.
-
 Access the attribute value of the first node of the current selection::
 
     $class = $crawler->filterXPath('//body/p')->attr('class');
@@ -245,11 +240,6 @@ Access the attribute value of the first node of the current selection::
 
         $class = $crawler->filterXPath('//body/p')->attr('class', 'my-default-class');
 
-    .. versionadded:: 6.4
-
-        The possibility to specify a default value to the ``attr()`` method
-        was introduced in Symfony 6.4.
-
 Extract attribute and/or node values from the list of nodes::
 
     $attributes = $crawler
@@ -672,10 +662,6 @@ parser, set its ``useHtml5Parser`` constructor argument to ``true``::
 By doing so, the crawler will use the HTML5 parser provided by the `masterminds/html5`_
 library to parse the documents.
 
-.. versionadded:: 6.3
-
-    The ``useHtml5Parser`` argument was introduced in Symfony 6.3.
-
 Learn more
 ----------
 
diff --git a/components/expression_language.rst b/components/expression_language.rst
index a08e77b01ea..a10ad6cfe1b 100644
--- a/components/expression_language.rst
+++ b/components/expression_language.rst
@@ -92,10 +92,6 @@ can chain multiple coalescing operators.
 * ``foo[3] ?? 'no'``
 * ``foo.baz ?? foo['baz'] ?? 'no'``
 
-.. versionadded:: 6.2
-
-    The null-coalescing operator was introduced in Symfony 6.2.
-
 Passing in Variables
 --------------------
 
diff --git a/components/finder.rst b/components/finder.rst
index 27dd6709b6d..ecf19fc1fe1 100644
--- a/components/finder.rst
+++ b/components/finder.rst
@@ -340,11 +340,6 @@ Sort the results by name, extension, size or type (directories first, then files
     $finder->sortBySize();
     $finder->sortByType();
 
-.. versionadded:: 6.2
-
-    The ``sortByCaseInsensitiveName()``, ``sortByExtension()`` and ``sortBySize()``
-    methods were introduced in Symfony 6.2.
-
 .. tip::
 
     By default, the ``sortByName()`` method uses the :phpfunction:`strcmp` PHP
diff --git a/components/http_foundation.rst b/components/http_foundation.rst
index 18d64d6b467..5c6d0dba0c7 100644
--- a/components/http_foundation.rst
+++ b/components/http_foundation.rst
@@ -145,11 +145,6 @@ has some methods to filter the input values:
 :method:`Symfony\\Component\\HttpFoundation\\ParameterBag::getString`
     Returns the parameter value as a string;
 
-.. versionadded:: 6.3
-
-    The ``ParameterBag::getEnum()`` and ``ParameterBag::getString()`` methods
-    were introduced in Symfony 6.3.
-
 :method:`Symfony\\Component\\HttpFoundation\\ParameterBag::filter`
     Filters the parameter by using the PHP :phpfunction:`filter_var` function.
     If invalid values are found, a
@@ -220,11 +215,6 @@ wrapping this data::
 
     $data = $request->getPayload();
 
-.. versionadded:: 6.3
-
-    The :method:`Symfony\\Component\\HttpFoundation\\Request::getPayload`
-    method was introduced in Symfony 6.3.
-
 Identifying a Request
 ~~~~~~~~~~~~~~~~~~~~~
 
@@ -389,10 +379,6 @@ use the ``isPrivateIp()`` method from the
     $isPrivate = IpUtils::isPrivateIp($ipv6);
     // $isPrivate = false
 
-.. versionadded:: 6.3
-
-    The ``isPrivateIp()`` method was introduced in Symfony 6.3.
-
 Accessing other Data
 ~~~~~~~~~~~~~~~~~~~~
 
@@ -562,11 +548,6 @@ call::
         'etag'             => 'abcdef',
     ]);
 
-.. versionadded:: 6.1
-
-    The ``stale_if_error`` and ``stale_while_revalidate`` options were
-    introduced in Symfony 6.1.
-
 To check if the Response validators (``ETag``, ``Last-Modified``) match a
 conditional value specified in the client Request, use the
 :method:`Symfony\\Component\\HttpFoundation\\Response::isNotModified`
@@ -629,11 +610,6 @@ represented by a PHP callable instead of a string::
 Streaming a JSON Response
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.3
-
-    The :class:`Symfony\\Component\\HttpFoundation\\StreamedJsonResponse` class was
-    introduced in Symfony 6.3.
-
 The :class:`Symfony\\Component\\HttpFoundation\\StreamedJsonResponse` allows to
 stream large JSON responses using PHP generators to keep the used resources low.
 
@@ -646,9 +622,9 @@ containing JSON serializable data::
 
     // any method or function returning a PHP Generator
     function loadArticles(): \Generator {
-         yield ['title' => 'Article 1'];
-         yield ['title' => 'Article 2'];
-         yield ['title' => 'Article 3'];
+        yield ['title' => 'Article 1'];
+        yield ['title' => 'Article 2'];
+        yield ['title' => 'Article 3'];
     };
 
     $response = new StreamedJsonResponse(
@@ -723,10 +699,6 @@ including generators::
         return new StreamedJsonResponse(loadArticles());
     }
 
-.. versionadded:: 6.4
-
-    The ``StreamedJsonResponse`` support of iterables was introduced in Symfony 6.4.
-
 .. _component-http-foundation-serving-files:
 
 Serving Files
diff --git a/components/http_kernel.rst b/components/http_kernel.rst
index 32f66f9ac2a..435ded9063a 100644
--- a/components/http_kernel.rst
+++ b/components/http_kernel.rst
@@ -280,10 +280,6 @@ Another typical use-case for this event is to retrieve the attributes from
 the controller using the :method:`Symfony\\Component\\HttpKernel\\Event\\ControllerEvent::getAttributes`
 method. See the Symfony section below for some examples.
 
-.. versionadded:: 6.2
-
-    The ``ControllerEvent::getAttributes()`` method was introduced in Symfony 6.2.
-
 Listeners to this event can also change the controller callable completely
 by calling :method:`ControllerEvent::setController <Symfony\\Component\\HttpKernel\\Event\\ControllerEvent::setController>`
 on the event object that's passed to listeners on this event.
@@ -343,13 +339,6 @@ of arguments that should be passed when executing that callable.
     ``ValueResolverInterface`` yourself and passing this to the
     ``ArgumentResolver``, you can extend this functionality.
 
-    .. versionadded:: 6.2
-
-        The ``ValueResolverInterface`` was introduced in Symfony 6.2. Prior to
-        6.2, you had to use the
-        :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface`,
-        which defines different methods.
-
 .. _component-http-kernel-calling-controller:
 
 5) Calling the Controller
diff --git a/components/intl.rst b/components/intl.rst
index 3981062f5b7..46146e47e1b 100644
--- a/components/intl.rst
+++ b/components/intl.rst
@@ -210,10 +210,6 @@ numeric country codes::
     $exists = Countries::numericCodeExists('250');
     // => true
 
-.. versionadded:: 6.4
-
-    The support for numeric country codes was introduced in Symfony 6.4.
-
 Locales
 ~~~~~~~
 
@@ -397,10 +393,6 @@ to catching the exception, you can also check if a given timezone ID is valid::
 Emoji Transliteration
 ~~~~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.2
-
-    The Emoji transliteration feature was introduced in Symfony 6.2.
-
 The ``EmojiTransliterator`` class provides a utility to translate emojis into
 their textual representation in all languages based on the `Unicode CLDR dataset`_::
 
@@ -448,10 +440,6 @@ Symfony emoji data files using the PHP ``zlib`` extension:
     # adjust the path to the 'compress' binary based on your application installation
     $ php ./vendor/symfony/intl/Resources/bin/compress
 
-.. versionadded:: 6.3
-
-    The ``compress`` binary was introduced in Symfony 6.3.
-
 Learn more
 ----------
 
diff --git a/components/lock.rst b/components/lock.rst
index 1c87942bb34..9e854ab89a6 100644
--- a/components/lock.rst
+++ b/components/lock.rst
@@ -553,11 +553,6 @@ the command:
 
     $ php bin/console make:migration
 
-.. versionadded:: 6.3
-
-    The automatic table generation when running the ``make:migration`` command
-    was introduced in Symfony 6.3.
-
 If you prefer to create the table yourself and it has not already been created, you can
 create this table explicitly by calling the
 :method:`Symfony\\Component\\Lock\\Store\\DoctrineDbalStore::createTable` method.
@@ -610,10 +605,6 @@ store locks and does not expire.
 RedisStore
 ~~~~~~~~~~
 
-.. versionadded:: 6.3
-
-    ``\Relay\Relay`` support was introduced in Symfony 6.3.
-
 The RedisStore saves locks on a Redis server, it requires a Redis connection
 implementing the ``\Redis``, ``\RedisArray``, ``\RedisCluster``, ``\Relay\Relay`` or
 ``\Predis`` classes. This store does not support blocking, and expects a TTL to
diff --git a/components/options_resolver.rst b/components/options_resolver.rst
index 46b0ee6d542..ddbdb878f4d 100644
--- a/components/options_resolver.rst
+++ b/components/options_resolver.rst
@@ -862,10 +862,6 @@ if an unknown option is passed. You can ignore not defined options by using the
         'version'  => '1.2.3'
     ]);
 
-.. versionadded:: 6.3
-
-    The ``ignoreUndefined()`` method was introduced in Symfony 6.3.
-
 Chaining Option Configurations
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/components/phpunit_bridge.rst b/components/phpunit_bridge.rst
index bfa69893bb9..0e92c345ad1 100644
--- a/components/phpunit_bridge.rst
+++ b/components/phpunit_bridge.rst
@@ -291,10 +291,6 @@ Here is a summary that should help you pick the right configuration:
 Ignoring Deprecations
 .....................
 
-.. versionadded:: 6.1
-
-    The ``ignoreFile`` feature was introduced in Symfony 6.1.
-
 If your application has some deprecations that you can't fix for some reasons,
 you can tell Symfony to ignore them.
 
@@ -541,10 +537,6 @@ allows you to mock the PHP's built-in time functions ``time()``, ``microtime()``
 function ``date()`` is mocked so it uses the mocked time if no timestamp is
 specified.
 
-.. versionadded:: 6.2
-
-    Support for mocking the ``hrtime()`` function was introduced in Symfony 6.2.
-
 Other functions with an optional timestamp parameter that defaults to ``time()``
 will still use the system time instead of the mocked time. This means that you
 may need to change some code in your tests. For example, instead of ``new DateTime()``,
@@ -741,10 +733,6 @@ reason, this component also provides mocks for these PHP functions:
 * :phpfunction:`trait_exists`
 * :phpfunction:`enum_exists`
 
-.. versionadded:: 6.3
-
-    The ``enum_exists`` function was introduced in Symfony 6.3.
-
 Use Case
 ~~~~~~~~
 
@@ -816,10 +804,6 @@ PHP 8.1 and later, calling ``class_exists`` on a enum will return ``true``.
 That's why calling ``ClassExistsMock::withMockedEnums()`` will also register the enum
 as a mocked class.
 
-.. versionadded:: 6.3
-
-    The ``enum_exists`` function was introduced in Symfony 6.3.
-
 Troubleshooting
 ---------------
 
diff --git a/components/process.rst b/components/process.rst
index 158b8d0bd5a..999dd9d1f2e 100644
--- a/components/process.rst
+++ b/components/process.rst
@@ -413,10 +413,6 @@ instead::
 Executing a PHP Child Process with the Same Configuration
 ---------------------------------------------------------
 
-.. versionadded:: 6.4
-
-    The ``PhpSubprocess`` helper was introduced in Symfony 6.4.
-
 When you start a PHP process, it uses the default configuration defined in
 your ``php.ini`` file. You can bypass these options with the ``-d`` command line
 option. For example, if ``memory_limit`` is set to ``256M``, you can disable this
diff --git a/components/property_access.rst b/components/property_access.rst
index c2a911e9b8e..1f3f28a6a1b 100644
--- a/components/property_access.rst
+++ b/components/property_access.rst
@@ -89,11 +89,6 @@ You can also use multi dimensional arrays::
 
     Right square brackets ``]`` don't need to be escaped in array keys.
 
-    .. versionadded:: 6.3
-
-        Escaping dots and left square brackets in a property path was
-        introduced in Symfony 6.3.
-
 Reading from Objects
 --------------------
 
@@ -236,10 +231,6 @@ is to mark all nullable properties with the nullsafe operator (``?``)::
     // no longer evaluated and null is returned immediately without throwing an exception
     var_dump($propertyAccessor->getValue($comment, 'person?.firstname')); // null
 
-.. versionadded:: 6.2
-
-    The ``?`` nullsafe operator was introduced in Symfony 6.2.
-
 .. _components-property-access-magic-get:
 
 Magic ``__get()`` Method
diff --git a/components/property_info.rst b/components/property_info.rst
index d5699ea1bab..38e00b5dfc1 100644
--- a/components/property_info.rst
+++ b/components/property_info.rst
@@ -229,12 +229,6 @@ works. It assumes camel case style method names following `PSR-1`_. For example,
 both ``myProperty`` and ``my_property`` properties are readable if there's a
 ``getMyProperty()`` method and writable if there's a ``setMyProperty()`` method.
 
-.. versionadded:: 6.4
-
-    In Symfony versions prior to 6.4, snake case properties (e.g. ``my_property``)
-    were not writable by camel case methods (e.g. ``setMyProperty()``). You had
-    to define method names with underscores (e.g. ``setMy_property()``).
-
 .. _property-info-initializable:
 
 Property Initializable Information
diff --git a/components/serializer.rst b/components/serializer.rst
index f879d5167c6..630ff1cf3b8 100644
--- a/components/serializer.rst
+++ b/components/serializer.rst
@@ -712,10 +712,6 @@ automatically detect and use it to serialize related attributes.
 The ``ObjectNormalizer`` also takes care of methods starting with ``has``, ``get``,
 and ``can``.
 
-.. versionadded:: 6.1
-
-    The support of canners (methods prefixed by ``can``) was introduced in Symfony 6.1.
-
 Using Callbacks to Serialize Properties with Object Instances
 -------------------------------------------------------------
 
@@ -811,11 +807,6 @@ The Serializer component provides several built-in normalizers:
     combine the following values: ``PropertyNormalizer::NORMALIZE_PUBLIC``,
     ``PropertyNormalizer::NORMALIZE_PROTECTED`` or ``PropertyNormalizer::NORMALIZE_PRIVATE``.
 
-    .. versionadded:: 6.2
-
-        The ``PropertyNormalizer::NORMALIZE_VISIBILITY`` context option and its
-        values were introduced in Symfony 6.2.
-
 :class:`Symfony\\Component\\Serializer\\Normalizer\\JsonSerializableNormalizer`
     This normalizer works with classes that implement :phpclass:`JsonSerializable`.
 
@@ -852,10 +843,6 @@ The Serializer component provides several built-in normalizers:
     By default, an exception is thrown when data is not a valid backed enumeration. If you
     want ``null`` instead, you can set the ``BackedEnumNormalizer::ALLOW_INVALID_VALUES`` option.
 
-    .. versionadded:: 6.3
-
-        The ``BackedEnumNormalizer::ALLOW_INVALID_VALUES`` context option was introduced in Symfony 6.3.
-
 :class:`Symfony\\Component\\Serializer\\Normalizer\\FormErrorNormalizer`
     This normalizer works with classes that implement
     :class:`Symfony\\Component\\Form\\FormInterface`.
@@ -896,11 +883,6 @@ The Serializer component provides several built-in normalizers:
     setting the ``TranslatableNormalizer::NORMALIZATION_LOCALE_KEY`` serializer
     context option.
 
-    .. versionadded:: 6.4
-
-        The :class:`Symfony\\Component\\Serializer\\Normalizer\\TranslatableNormalizer`
-        was introduced in Symfony 6.4.
-
 .. note::
 
     You can also create your own Normalizer to use another structure. Read more at
@@ -1030,10 +1012,6 @@ Option                           Description
 ``json_decode_recursion_depth``  Sets maximum recursion depth.                                                                               ``512``
 ===============================  ==========================================================================================================  ================================
 
-.. versionadded:: 6.4
-
-    The support of ``json_decode_detailed_errors`` was introduced in Symfony 6.4.
-
 The ``CsvEncoder``
 ~~~~~~~~~~~~~~~~~~
 
@@ -1252,10 +1230,6 @@ you can use "context builders" to define the context using a fluent interface::
 
     $serializer->serialize($something, 'csv', $contextBuilder->toArray());
 
-.. versionadded:: 6.1
-
-    Context builders were introduced in Symfony 6.1.
-
 .. note::
 
     The Serializer component provides a context builder
diff --git a/components/string.rst b/components/string.rst
index ca289c70ba4..f743849fd19 100644
--- a/components/string.rst
+++ b/components/string.rst
@@ -565,10 +565,6 @@ the injected slugger is the same as the request locale::
 Slug Emojis
 ~~~~~~~~~~~
 
-.. versionadded:: 6.2
-
-    The Emoji transliteration feature was introduced in Symfony 6.2.
-
 You can transform any emojis into their textual representation::
 
     use Symfony\Component\String\Slugger\AsciiSlugger;
@@ -603,10 +599,6 @@ If you want to strip emojis from slugs, use the special ``strip`` locale::
     $slug = $slugger->slug('a 😺, 🐈‍⬛, and a 🦁');
     // $slug = 'a-and-a';
 
-.. versionadded:: 6.3
-
-    The option to strip emojis from slugs was introduced in Symfony 6.3.
-
 .. _string-inflector:
 
 Inflector
diff --git a/components/uid.rst b/components/uid.rst
index 52403513995..26fd32989a9 100644
--- a/components/uid.rst
+++ b/components/uid.rst
@@ -70,10 +70,6 @@ to create each type of UUID::
     // UUIDv8 uniqueness will be implementation-specific and SHOULD NOT be assumed.
     $uuid = Uuid::v8();
 
-.. versionadded:: 6.2
-
-    UUID versions 7 and 8 were introduced in Symfony 6.2.
-
 If your UUID value is already generated in another format, use any of the
 following methods to create a ``Uuid`` object from it::
 
@@ -184,10 +180,6 @@ Use these methods to transform the UUID object into different bases::
     $uuid->toRfc4122(); // string(36) "d9e7a184-5d5b-11ea-a62a-3499710062d0"
     $uuid->toHex();     // string(34) "0xd9e7a1845d5b11eaa62a3499710062d0"
 
-.. versionadded:: 6.2
-
-    The ``toHex()`` method was introduced in Symfony 6.2.
-
 Working with UUIDs
 ~~~~~~~~~~~~~~~~~~
 
@@ -247,10 +239,6 @@ type, which converts to/from UUID objects automatically::
         // ...
     }
 
-.. versionadded:: 6.2
-
-    The ``UuidType::NAME`` constant was introduced in Symfony 6.2.
-
 There's also a Doctrine generator to help auto-generate UUID values for the
 entity primary keys::
 
@@ -387,10 +375,6 @@ Use these methods to transform the ULID object into different bases::
     $ulid->toRfc4122(); // string(36) "0171069d-593d-97d3-8b3e-23d06de5b308"
     $ulid->toHex();     // string(34) "0x0171069d593d97d38b3e23d06de5b308"
 
-.. versionadded:: 6.2
-
-    The ``toHex()`` method was introduced in Symfony 6.2.
-
 Working with ULIDs
 ~~~~~~~~~~~~~~~~~~
 
@@ -434,10 +418,6 @@ type, which converts to/from ULID objects automatically::
         // ...
     }
 
-.. versionadded:: 6.2
-
-    The ``UlidType::NAME`` constant was introduced in Symfony 6.2.
-
 There's also a Doctrine generator to help auto-generate ULID values for the
 entity primary keys::
 
diff --git a/components/validator/resources.rst b/components/validator/resources.rst
index d9d3543a641..d9b63a147d5 100644
--- a/components/validator/resources.rst
+++ b/components/validator/resources.rst
@@ -86,11 +86,6 @@ configure the locations of these files::
 The AttributeLoader
 -------------------
 
-.. versionadded:: 6.4
-
-    The :class:`Symfony\\Component\\Validator\\Mapping\\Loader\\AttributeLoader`
-    was introduced in Symfony 6.4.
-
 The component provides an
 :class:`Symfony\\Component\\Validator\\Mapping\\Loader\\AttributeLoader` to get
 the metadata from the attributes of the class. For example::
diff --git a/components/var_dumper.rst b/components/var_dumper.rst
index 6b336ad1d3e..06adc3a0021 100644
--- a/components/var_dumper.rst
+++ b/components/var_dumper.rst
@@ -485,10 +485,6 @@ then its dump representation::
 .. image:: /_images/components/var_dumper/10-uninitialized.png
     :alt: Dump output where the uninitialized property is represented by a question mark followed by the type definition.
 
-.. versionadded:: 6.4
-
-    Displaying uninitialized variables information was introduced in Symfony 6.4.
-
 .. _var-dumper-advanced:
 
 Advanced Usage
diff --git a/components/var_exporter.rst b/components/var_exporter.rst
index 12c1396b0f1..17e2112210a 100644
--- a/components/var_exporter.rst
+++ b/components/var_exporter.rst
@@ -177,10 +177,6 @@ populated by using the special ``"\0"`` property name to define their internal v
         "\0" => [$inputArray],
     ]);
 
-.. versionadded:: 6.2
-
-    The :class:`Symfony\\Component\\VarExporter\\Hydrator` was introduced in Symfony 6.2.
-
 Creating Lazy Objects
 ---------------------
 
@@ -288,10 +284,6 @@ Ghost objects unfortunately can't work with abstract classes or internal PHP
 classes. Nevertheless, the VarExporter component covers this need with the help
 of :ref:`Virtual Proxies <var-exporter_virtual-proxies>`.
 
-.. versionadded:: 6.2
-
-    The :class:`Symfony\\Component\\VarExporter\\LazyGhostTrait` was introduced in Symfony 6.2.
-
 .. _var-exporter_virtual-proxies:
 
 LazyProxyTrait
@@ -357,10 +349,5 @@ Just like ghost objects, while you never query ``$processor->hash``, its value
 will not be computed. The main difference with ghost objects is that this time,
 a proxy of an abstract class was created. This also works with internal PHP class.
 
-.. versionadded:: 6.2
-
-    The :class:`Symfony\\Component\\VarExporter\\LazyProxyTrait` and
-    :class:`Symfony\\Component\\VarExporter\\ProxyHelper` were introduced in Symfony 6.2.
-
 .. _`OPcache`: https://www.php.net/opcache
 .. _`PSR-2`: https://www.php-fig.org/psr/psr-2/
diff --git a/components/yaml.rst b/components/yaml.rst
index 37d8064f235..ab4c0b6be22 100644
--- a/components/yaml.rst
+++ b/components/yaml.rst
@@ -355,10 +355,6 @@ and the special ``!php/enum`` syntax to parse them as proper PHP enums::
     // the value of the 'foo' key is a string because it missed the `!php/enum` syntax
     // $parameters = ['foo' => 'FooEnum::Foo', 'bar' => 'foo'];
 
-.. versionadded:: 6.2
-
-    The support for PHP enumerations was introduced in Symfony 6.2.
-
 Parsing and Dumping of Binary Data
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -422,10 +418,6 @@ By default, digit-only array keys are dumped as integers. You can use the
     $dumped = Yaml::dump([200 => 'foo'], 2, 4, Yaml::DUMP_NUMERIC_KEY_AS_STRING);
     // '200': foo
 
-.. versionadded:: 6.3
-
-    The ``DUMP_NUMERIC_KEY_AS_STRING`` flag was introduced in Symfony 6.3.
-
 Syntax Validation
 ~~~~~~~~~~~~~~~~~
 
diff --git a/configuration.rst b/configuration.rst
index e4a923c5858..bcdebade23a 100644
--- a/configuration.rst
+++ b/configuration.rst
@@ -81,10 +81,6 @@ readable. These are the main advantages and disadvantages of each format:
     methods in the ``src/Kernel.php`` file to add support for the ``.xml`` file
     extension.
 
-    .. versionadded:: 6.1
-
-        The automatic loading of PHP configuration files was introduced in Symfony 6.1.
-
 Importing Configuration Files
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -292,14 +288,6 @@ reusable configuration value. By convention, parameters are defined under the
             something@example.com
         </parameter>
 
-.. versionadded:: 6.2
-
-    Passing an enum case as a service parameter was introduced in Symfony 6.2.
-
-.. versionadded:: 6.3
-
-    The ``trim`` attribute was introduced in Symfony 6.3.
-
 Once defined, you can reference this parameter value from any other
 configuration file using a special syntax: wrap the parameter name in two ``%``
 (e.g. ``%app.admin_email%``):
@@ -395,10 +383,6 @@ a new ``locale`` parameter is added to the ``config/services.yaml`` file).
     They are useful when working with :ref:`Compiler Passes </service_container/compiler_passes>`
     to declare some temporary parameters that won't be available later in the application.
 
-.. versionadded:: 6.3
-
-    Compile-time parameters were introduced in Symfony 6.3.
-
 .. seealso::
 
     Later in this article you can read how to
@@ -984,10 +968,6 @@ Use the ``debug:dotenv`` command to understand how Symfony parses the different
     # look for a specific variable passing its full or partial name as an argument
     $ php bin/console debug:dotenv foo
 
-.. versionadded:: 6.2
-
-    The option to pass variable names to ``debug:dotenv`` was introduced in Symfony 6.2.
-
 Additionally, and regardless of how you set environment variables, you can see all
 environment variables, with their values, referenced in Symfony's container configuration:
 
diff --git a/configuration/env_var_processors.rst b/configuration/env_var_processors.rst
index 4f600a5b34b..eba9f4a482c 100644
--- a/configuration/env_var_processors.rst
+++ b/configuration/env_var_processors.rst
@@ -418,10 +418,6 @@ Symfony provides the following env var processors:
                     ->set(\RedisCluster::class, \RedisCluster::class)->args([null, '%env(shuffle:csv:REDIS_NODES)%']);
             };
 
-    .. versionadded:: 6.2
-
-        The ``env(shuffle:...)`` env var processor was introduced in Symfony 6.2.
-
 ``env(file:FOO)``
     Returns the contents of a file whose path is the value of the ``FOO`` env var:
 
@@ -782,10 +778,6 @@ Symfony provides the following env var processors:
             // config/services.php
             $container->setParameter('typed_env', '%env(enum:App\Enum\Environment:APP_ENV)%');
 
-    .. versionadded:: 6.2
-
-        The ``env(enum:...)`` env var processor was introduced in Symfony 6.2.
-
 ``env(defined:NO_FOO)``
     Evaluates to ``true`` if the env var exists and its value is not ``''``
     (an empty string) or ``null``; it returns ``false`` otherwise.
@@ -820,10 +812,6 @@ Symfony provides the following env var processors:
             // config/services.php
             $container->setParameter('typed_env', '%env(defined:FOO)%');
 
-    .. versionadded:: 6.4
-
-        The ``env(defined:...)`` env var processor was introduced in Symfony 6.4.
-
 It is also possible to combine any number of processors:
 
 .. configuration-block::
diff --git a/configuration/micro_kernel_trait.rst b/configuration/micro_kernel_trait.rst
index 890f3fc8b9c..26a332e4fdd 100644
--- a/configuration/micro_kernel_trait.rst
+++ b/configuration/micro_kernel_trait.rst
@@ -120,10 +120,6 @@ Next, create an ``index.php`` file that defines the kernel class and runs it:
         $response->send();
         $kernel->terminate($request, $response);
 
-.. versionadded:: 6.1
-
-    The PHP attributes notation has been introduced in Symfony 6.1.
-
 That's it! To test it, start the :doc:`Symfony Local Web Server
 </setup/symfony_server>`:
 
@@ -338,10 +334,6 @@ add a service conditionally based on the ``foo`` value::
         }
     }
 
-.. versionadded:: 6.1
-
-    The ``AbstractExtension`` class was introduced in Symfony 6.1.
-
 Unlike the previous kernel, this loads an external ``config/framework.yaml`` file,
 because the configuration started to get bigger:
 
diff --git a/console.rst b/console.rst
index 1f468327d61..136d4c7f8fe 100644
--- a/console.rst
+++ b/console.rst
@@ -67,14 +67,6 @@ command, for instance:
 Console Completion
 ~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.1
-
-    Console completion for Fish was introduced in Symfony 6.1.
-
-.. versionadded:: 6.2
-
-    Console completion for Zsh was introduced in Symfony 6.2.
-
 If you are using the Bash, Zsh or Fish shell, you can install Symfony's
 completion script to get auto completion when typing commands in the
 terminal. All commands support name and option completion, and some can
@@ -356,10 +348,6 @@ method, which returns an instance of
 
     A new line is appended automatically when displaying information in a section.
 
-.. versionadded:: 6.2
-
-    The feature to limit the height of a console section was introduced in Symfony 6.2.
-
 Output sections let you manipulate the Console output in advanced ways, such as
 :ref:`displaying multiple progress bars <console-multiple-progress-bars>` which
 are updated independently and :ref:`appending rows to tables <console-modify-rendered-tables>`
diff --git a/console/coloring.rst b/console/coloring.rst
index a481b7650ff..346e0818a41 100644
--- a/console/coloring.rst
+++ b/console/coloring.rst
@@ -56,10 +56,6 @@ Any hex color is supported for foreground and background colors. Besides that, t
     the nearest color depending on the terminal capabilities. E.g. ``#c0392b`` is
     degraded to ``#d75f5f`` in 256-color terminals and to ``red`` in 8-color terminals.
 
-    .. versionadded:: 6.2
-
-        The support for 256-color terminals was introduced in Symfony 6.2.
-
 And available options are: ``bold``, ``underscore``, ``blink``, ``reverse``
 (enables the "reverse video" mode where the background and foreground colors
 are swapped) and ``conceal`` (sets the foreground color to transparent, making
diff --git a/console/input.rst b/console/input.rst
index ed637bdba74..4d709c18825 100644
--- a/console/input.rst
+++ b/console/input.rst
@@ -354,12 +354,6 @@ To achieve this, use the 5th argument of ``addArgument()``/``addOption``::
         }
     }
 
-.. versionadded:: 6.1
-
-    The argument to ``addOption()``/``addArgument()`` was introduced in
-    Symfony 6.1. Prior to this version, you had to override the
-    ``complete()`` method of the command.
-
 That's all you need! Assuming users "Fabien" and "Fabrice" exist, pressing
 tab after typing ``app:greet Fa`` will give you these names as a suggestion.
 
diff --git a/console/style.rst b/console/style.rst
index bcc4d982457..0aaaa3f675e 100644
--- a/console/style.rst
+++ b/console/style.rst
@@ -333,10 +333,6 @@ User Input Methods
 
         $io->choice('Select the queue to analyze', ['queue1', 'queue2', 'queue3'], multiSelect: true);
 
-.. versionadded:: 6.2
-
-    The ``multiSelect`` option of ``choice()`` was introduced in Symfony 6.2.
-
 .. _symfony-style-blocks:
 
 Result Methods
@@ -445,10 +441,6 @@ If you prefer to wrap all contents, including URLs, use this method::
         }
     }
 
-.. versionadded:: 6.2
-
-    The ``setAllowCutUrls()`` method was introduced in Symfony 6.2.
-
 Defining your Own Styles
 ------------------------
 
diff --git a/contributing/documentation/format.rst b/contributing/documentation/format.rst
index b403169cbaf..d933f3bcead 100644
--- a/contributing/documentation/format.rst
+++ b/contributing/documentation/format.rst
@@ -251,34 +251,34 @@ directive:
 
 .. code-block:: rst
 
-    .. versionadded:: 6.2
+    .. versionadded:: 7.2
 
-        ... ... ... was introduced in Symfony 6.2.
+        ... ... ... was introduced in Symfony 7.2.
 
 If you are documenting a behavior change, it may be helpful to *briefly*
 describe how the behavior has changed:
 
 .. code-block:: rst
 
-    .. versionadded:: 6.2
+    .. versionadded:: 7.2
 
-       ... ... ... was introduced in Symfony 6.2. Prior to this,
+       ... ... ... was introduced in Symfony 7.2. Prior to this,
        ... ... ... ... ... ... ... ... .
 
-For a deprecation use the ``.. deprecated:: 6.x`` directive:
+For a deprecation use the ``.. deprecated:: 7.x`` directive:
 
 .. code-block:: rst
 
-    .. deprecated:: 6.2
+    .. deprecated:: 7.2
 
-        ... ... ... was deprecated in Symfony 6.2.
+        ... ... ... was deprecated in Symfony 7.2.
 
-Whenever a new major version of Symfony is released (e.g. 7.0, 8.0, etc), a new
+Whenever a new major version of Symfony is released (e.g. 8.0, 9.0, etc), a new
 branch of the documentation is created from the ``x.4`` branch of the previous
 major version. At this point, all the ``versionadded`` and ``deprecated`` tags
 for Symfony versions that have a lower major version will be removed. For
-example, if Symfony 7.0 were released today, 6.0 to 6.4 ``versionadded`` and
-``deprecated`` tags would be removed from the new ``7.0`` branch.
+example, if Symfony 8.0 were released today, 7.0 to 7.4 ``versionadded`` and
+``deprecated`` tags would be removed from the new ``8.0`` branch.
 
 .. _reStructuredText: https://docutils.sourceforge.io/rst.html
 .. _Sphinx: https://www.sphinx-doc.org/
diff --git a/controller.rst b/controller.rst
index 7afae06f728..891416d8aeb 100644
--- a/controller.rst
+++ b/controller.rst
@@ -229,10 +229,6 @@ command:
 
     You can read more about this attribute in :ref:`autowire-attribute`.
 
-    .. versionadded:: 6.1
-
-        The ``#[Autowire]`` attribute was introduced in Symfony 6.1.
-
 Like with all services, you can also use regular
 :ref:`constructor injection <services-constructor-injection>` in your
 controllers.
@@ -383,11 +379,6 @@ attribute, arguments of your controller's action can be automatically fulfilled:
         // ...
     }
 
-.. versionadded:: 6.3
-
-    The :class:`Symfony\\Component\\HttpKernel\\Attribute\\MapQueryParameter` attribute
-    was introduced in Symfony 6.3.
-
 Mapping The Whole Query String
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -449,15 +440,6 @@ HTTP status to return if the validation fails::
 
 The default status code returned if the validation fails is 404.
 
-.. versionadded:: 6.3
-
-    The :class:`Symfony\\Component\\HttpKernel\\Attribute\\MapQueryString` attribute
-    was introduced in Symfony 6.3.
-
-.. versionadded:: 6.4
-
-    The ``validationFailedStatusCode`` parameter was introduced in Symfony 6.4.
-
 Mapping Request Payload
 ~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -546,15 +528,6 @@ if you want to map a nested array of specific DTOs::
         ) {}
     }
 
-.. versionadded:: 6.3
-
-    The :class:`Symfony\\Component\\HttpKernel\\Attribute\\MapRequestPayload` attribute
-    was introduced in Symfony 6.3.
-
-.. versionadded:: 6.4
-
-    The ``validationFailedStatusCode`` parameter was introduced in Symfony 6.4.
-
 Managing the Session
 --------------------
 
@@ -728,11 +701,6 @@ The ``file()`` helper provides some arguments to configure its behavior::
 Sending Early Hints
 ~~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.3
-
-    The Early Hints helper of the ``AbstractController`` was introduced
-    in Symfony 6.3.
-
 `Early hints`_ tell the browser to start downloading some assets even before the
 application sends the response content. This improves perceived performance
 because the browser can prefetch resources that will be needed once the full
diff --git a/controller/value_resolver.rst b/controller/value_resolver.rst
index 71efd680b08..abefc0efbb3 100644
--- a/controller/value_resolver.rst
+++ b/controller/value_resolver.rst
@@ -75,10 +75,6 @@ Symfony ships with the following value resolvers in the
     The example above allows requesting only ``/cards/D`` and ``/cards/S``
     URLs and leads to 404 Not Found response in two other cases.
 
-    .. versionadded:: 6.1
-
-        The ``BackedEnumValueResolver`` and ``EnumRequirement`` were introduced in Symfony 6.1.
-
 :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver\\RequestAttributeValueResolver`
     Attempts to find a request attribute that matches the name of the argument.
 
@@ -98,16 +94,6 @@ Symfony ships with the following value resolvers in the
         receives when testing your application and using the
         :class:`Symfony\\Component\\Clock\\MockClock` implementation.
 
-    .. versionadded:: 6.1
-
-        The ``DateTimeValueResolver`` and the ``MapDateTime`` attribute were
-        introduced in Symfony 6.1.
-
-    .. versionadded:: 6.3
-
-        The use of the :doc:`Clock component </components/clock>` to generate the
-        ``DateTimeInterface`` object was introduced in Symfony 6.3.
-
 :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver\\RequestValueResolver`
     Injects the current ``Request`` if type-hinted with ``Request`` or a class
     extending ``Request``.
@@ -147,10 +133,6 @@ Symfony ships with the following value resolvers in the
             }
         }
 
-    .. versionadded:: 6.1
-
-        The ``UidValueResolver`` was introduced in Symfony 6.1.
-
 :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver\\VariadicValueResolver`
     Verifies if the request data is an array and will add all of them to the
     argument list. When the action is called, the last (variadic) argument will
@@ -176,10 +158,6 @@ In addition, some components, bridges and official bundles provide other value r
     If the argument is not nullable and there is no logged in token, an ``HttpException``
     with status code 401 is thrown by the resolver to prevent access to the controller.
 
-    .. versionadded:: 6.3
-
-        The ``SecurityTokenValueResolver`` was introduced in Symfony 6.3.
-
 :class:`Symfony\\Bridge\\Doctrine\\ArgumentResolver\\EntityValueResolver`
     Automatically query for an entity and pass it as an argument to your controller.
 
@@ -203,10 +181,6 @@ In addition, some components, bridges and official bundles provide other value r
     To learn more about the use of the ``EntityValueResolver``, see the dedicated
     section :ref:`Automatically Fetching Objects <doctrine-entity-value-resolver>`.
 
-    .. versionadded:: 6.2
-
-        The ``EntityValueResolver`` was introduced in Symfony 6.2.
-
 PSR-7 Objects Resolver:
     Injects a Symfony HttpFoundation ``Request`` object created from a PSR-7 object
     of type :class:`Psr\\Http\\Message\\ServerRequestInterface`,
@@ -252,10 +226,6 @@ lets you do this by "targeting" the resolver you want::
         }
     }
 
-.. versionadded:: 6.3
-
-    The ``ValueResolver`` attribute was introduced in Symfony 6.3.
-
 In the example above, the ``SessionValueResolver`` will be called first because
 it is targeted. The ``DefaultValueResolver`` will be called next if no value has
 been provided; that's why you can assign ``null`` as ``$session``'s default value.
@@ -289,13 +259,6 @@ object whenever a controller argument has a type implementing
         }
     }
 
-.. versionadded:: 6.2
-
-    The ``ValueResolverInterface`` was introduced in Symfony 6.2. Prior to
-    6.2, you had to use the
-    :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface`,
-    which defines different methods.
-
 Adding a new value resolver requires creating a class that implements
 :class:`Symfony\\Component\\HttpKernel\\Controller\\ValueResolverInterface`
 and defining a service for it.
@@ -469,8 +432,3 @@ You can then pass this name as ``ValueResolver``'s first argument to target your
             // ... do something with $id
         }
     }
-
-.. versionadded:: 6.3
-
-    The ``controller.targeted_value_resolver`` tag and ``AsTargetedValueResolver``
-    attribute were introduced in Symfony 6.3.
diff --git a/doctrine.rst b/doctrine.rst
index 0e8cd614598..b1931c5ddf8 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -606,10 +606,6 @@ the :ref:`doctrine-queries` section.
 Automatically Fetching Objects (EntityValueResolver)
 ----------------------------------------------------
 
-.. versionadded:: 6.2
-
-    Entity Value Resolver was introduced in Symfony 6.2.
-
 .. versionadded:: 2.7.1
 
     Autowiring of the ``EntityValueResolver`` was introduced in DoctrineBundle 2.7.1.
@@ -758,11 +754,6 @@ variable. Let's say you pass the page limit of a list in a query parameter::
     ): Response {
     }
 
-.. versionadded:: 6.4
-
-    The support for the ``request`` variable in expressions was introduced
-    in Symfony 6.4.
-
 MapEntity Options
 ~~~~~~~~~~~~~~~~~
 
diff --git a/form/unit_testing.rst b/form/unit_testing.rst
index e191676215c..fbaa067858e 100644
--- a/form/unit_testing.rst
+++ b/form/unit_testing.rst
@@ -249,9 +249,4 @@ All you need to do is to implement the
 :method:`Symfony\\Bridge\\Twig\\Test\\FormLayoutTestCase::getTwigExtensions` and
 the :method:`Symfony\\Bridge\\Twig\\Test\\FormLayoutTestCase::getThemes` methods.
 
-.. versionadded:: 6.4
-
-    The :class:`Symfony\\Bridge\\Twig\\Test\\FormLayoutTestCase` class was
-    introduced in Symfony 6.4.
-
 .. _`PHPUnit data providers`: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#data-providers
diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index 8e655d69570..8317e5e3ecb 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -1,10 +1,6 @@
 AssetMapper: Simple, Modern CSS & JS Management
 ===============================================
 
-.. versionadded:: 6.3
-
-    The AssetMapper component was introduced in Symfony 6.3.
-
 The AssetMapper component lets you write modern JavaScript and CSS without the complexity
 of using a bundler. Browsers *already* support many modern JavaScript features
 like the ``import`` statement and ES6 classes. And the HTTP/2 protocol means that
@@ -238,10 +234,6 @@ directory and not commit it to your repository. Therefore, you'll need to run th
 ``php bin/console importmap:install`` command to download the files on other
 computers if some files are missing.
 
-.. versionadded:: 6.4
-
-    The ``importmap:install`` command was introduced in Symfony 6.4.
-
 .. note::
 
     Sometimes, a package - like ``bootstrap`` - will have one or more dependencies,
@@ -258,10 +250,6 @@ You can check for available updates for your third-party packages by running:
     # check for updates for the given list of packages
     $ php bin/console importmap:outdated bootstrap lodash
 
-.. versionadded:: 6.4
-
-    The ``importmap:outdated`` command was introduced in Symfony 6.4.
-
 To update third-party packages in your ``importmap.php`` file, run:
 
 .. code-block:: terminal
@@ -680,11 +668,6 @@ same way::
 If the :doc:`WebLink Component </web_link>` is available in your application,
 Symfony will add a ``Link`` header in the response to preload the CSS files.
 
-.. versionadded:: 6.4
-
-    Automatic preloading of CSS files when WebLink is available was
-    introduced in Symfony 6.4.
-
 Frequently Asked Questions
 --------------------------
 
@@ -1101,10 +1084,6 @@ command as part of your CI to be warned anytime a new vulnerability is found.
     The command takes a ``--format`` option to choose the output format between
     ``txt`` and ``json``.
 
-.. versionadded:: 6.4
-
-    The ``importmap:audit`` command was introduced in Symfony 6.4.
-
 .. _latest asset-mapper recipe: https://github.com/symfony/recipes/tree/main/symfony/asset-mapper
 .. _import statement: https://caniuse.com/es6-module-dynamic-import
 .. _ES6: https://caniuse.com/es6
diff --git a/html_sanitizer.rst b/html_sanitizer.rst
index baef54e79d4..ea6eb0c8106 100644
--- a/html_sanitizer.rst
+++ b/html_sanitizer.rst
@@ -1,10 +1,6 @@
 HTML Sanitizer
 ==============
 
-.. versionadded:: 6.1
-
-    The HTML Sanitizer component was introduced in Symfony 6.1.
-
 The HTML Sanitizer component aims at sanitizing/cleaning untrusted HTML
 code (e.g. created by a WYSIWYG editor in the browser) into HTML that can
 be trusted. It is based on the `HTML Sanitizer W3C Standard Proposal`_.
diff --git a/http_cache.rst b/http_cache.rst
index e1f1a57399c..38badf3a5c4 100644
--- a/http_cache.rst
+++ b/http_cache.rst
@@ -229,10 +229,6 @@ The *easiest* way to cache a response is by caching it for a specific amount of
             return $response;
         }
 
-.. versionadded:: 6.2
-
-    The ``#[Cache()]`` attribute was introduced in Symfony 6.2.
-
 Thanks to this new code, your HTTP response will have the following header:
 
 .. code-block:: text
diff --git a/http_cache/esi.rst b/http_cache/esi.rst
index aaf1de564c1..52a09fb16a7 100644
--- a/http_cache/esi.rst
+++ b/http_cache/esi.rst
@@ -279,8 +279,4 @@ The ``render_esi`` helper supports three other useful options:
 ``absolute_uri``
      If set to true, an absolute URI will be generated. **default**: ``false``
 
-.. versionadded:: 6.2
-
-    The ``absolute_uri`` option was introduced in Symfony 6.2.
-
 .. _`ESI`: https://www.w3.org/TR/esi-lang/
diff --git a/http_client.rst b/http_client.rst
index 7b45c2cf2b4..083d6c83e70 100644
--- a/http_client.rst
+++ b/http_client.rst
@@ -618,13 +618,6 @@ of the opened file, but you can configure both with the PHP streaming configurat
     stream_context_set_option($fileHandle, 'http', 'filename', 'the-name.txt');
     stream_context_set_option($fileHandle, 'http', 'content_type', 'my/content-type');
 
-.. versionadded:: 6.3
-
-    The feature to upload files using handles was introduced in Symfony 6.3.
-    In previous Symfony versions you had to encode the body contents according
-    to the ``multipart/form-data`` content-type using the :doc:`Symfony Mime </components/mime>`
-    component.
-
 .. tip::
 
     When using multidimensional arrays the :class:`Symfony\\Component\\Mime\\Part\\Multipart\\FormDataPart`
@@ -717,10 +710,6 @@ when using any HTTP method and ``500``, ``504``, ``507`` and ``510`` when using
 an HTTP `idempotent method`_. Use the ``max_retries`` setting to configure the
 amount of times a request is retried.
 
-.. versionadded:: 6.4
-
-    The ``max_retries`` options was introduced in Symfony 6.4.
-
 Check out the full list of configurable :ref:`retry_failed options <reference-http-client-retry-failed>`
 to learn how to tweak each of them to fit your application needs.
 
@@ -740,10 +729,6 @@ each retry.
 Retry Over Several Base URIs
 ............................
 
-.. versionadded:: 6.3
-
-    The multiple ``base_uri`` feature was added in Symfony 6.3.
-
 The ``RetryableHttpClient`` can be configured to use multiple base URIs. This
 feature provides increased flexibility and reliability for making HTTP
 requests. Pass an array of base URIs as option ``base_uri`` when making a
@@ -962,11 +947,6 @@ If you want to define your own logic to handle variables of URI templates, you
 can do so by redefining the ``http_client.uri_template_expander`` alias. Your
 service must be invokable.
 
-.. versionadded:: 6.3
-
-    The :class:`Symfony\\Component\\HttpClient\\UriTemplateHttpClient` was
-    introduced in Symfony 6.3.
-
 Performance
 -----------
 
@@ -1525,10 +1505,6 @@ to wrap your HTTP client, open a connection to a server that responds with a
     use the :method:`Symfony\\Component\\HttpClient\\Chunk\\ServerSentEvent::getArrayData`
     method to directly get the decoded JSON as array.
 
-.. versionadded:: 6.3
-
-    The ``ServerSentEvent::getArrayData()`` method was introduced in Symfony 6.3.
-
 Interoperability
 ----------------
 
@@ -1646,10 +1622,6 @@ You can also pass a set of default options to your client thanks to the
 
     // ...
 
-.. versionadded:: 6.2
-
-    The ``Psr18Client::withOptions()`` method was introduced in Symfony 6.2.
-
 HTTPlug
 ~~~~~~~
 
@@ -1751,10 +1723,6 @@ You can also pass a set of default options to your client thanks to the
 
     // ...
 
-.. versionadded:: 6.2
-
-    The ``HttplugClient::withOptions()`` method was introduced in Symfony 6.2.
-
 Native PHP Streams
 ~~~~~~~~~~~~~~~~~~
 
@@ -2096,10 +2064,6 @@ You can use :class:`Symfony\\Component\\HttpClient\\Response\\JsonMockResponse`
         'foo' => 'bar',
     ]);
 
-.. versionadded:: 6.3
-
-    The ``JsonMockResponse`` was introduced in Symfony 6.3.
-
 Testing Request Data
 ~~~~~~~~~~~~~~~~~~~~
 
@@ -2251,10 +2215,6 @@ will find the associated response based on the request method, URL and body (if
 Note that **this won't work** if the request body or URI is random / always
 changing (e.g. if it contains current date or random UUIDs).
 
-.. versionadded:: 6.4
-
-    The ``HarFileResponseFactory`` was introduced in Symfony 6.4.
-
 Testing Network Transport Exceptions
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -2301,12 +2261,6 @@ you to do so, by yielding the exception from its body::
         }
     }
 
-.. versionadded:: 6.1
-
-    Being allowed to pass an exception directly to the body of a
-    :class:`Symfony\\Component\\HttpClient\\Response\\MockResponse` was
-    introduced in Symfony 6.1.
-
 .. _`cURL PHP extension`: https://www.php.net/curl
 .. _`Zlib PHP extension`: https://www.php.net/zlib
 .. _`PSR-17`: https://www.php-fig.org/psr/psr-17/
diff --git a/lock.rst b/lock.rst
index 35c3dc5be3c..d70f1d5535b 100644
--- a/lock.rst
+++ b/lock.rst
@@ -159,11 +159,6 @@ this behavior by using the ``lock`` key like:
             ;
         };
 
-.. versionadded:: 6.1
-
-    The CSV support (e.g. ``zookeeper://localhost01,localhost02:2181``) in
-    ZookeeperStore DSN was introduced in Symfony 6.1.
-
 Locking a Resource
 ------------------
 
diff --git a/mailer.rst b/mailer.rst
index fb05b7fe668..155ad1623a3 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -115,21 +115,6 @@ Service               Install with
 `SendGrid`_           ``composer require symfony/sendgrid-mailer``
 ===================== ==============================================
 
-.. versionadded:: 6.2
-
-    The Infobip integration was introduced in Symfony 6.2 and the ``MailPace``
-    integration was renamed in Symfony 6.2 (in previous Symfony versions it was
-    called ``OhMySMTP``).
-
-.. versionadded:: 6.3
-
-    The MailerSend integration was introduced in Symfony 6.3.
-
-.. versionadded:: 6.4
-
-    The ``Brevo`` (in previous Symfony versions it was called ``Sendinblue``)
-    and ``Scaleway`` integrations were introduced in Symfony 6.4.
-
 .. note::
 
     As a convenience, Symfony also provides support for Gmail (``composer
@@ -227,10 +212,6 @@ party provider:
 |                        | - API sendgrid+api://KEY@default                    |
 +------------------------+-----------------------------------------------------+
 
-.. versionadded:: 6.3
-
-    The ``sandbox`` option in ``Mailjet`` API was introduced in Symfony 6.3.
-
 .. caution::
 
     If your credentials contain special characters, you must URL-encode them.
@@ -344,10 +325,6 @@ may be specified as SHA1 or MD5 hash::
 
     $dsn = 'smtp://user:pass@smtp.example.com?peer_fingerprint=6A1CF3B08D175A284C30BC10DE19162307C7286E';
 
-.. versionadded:: 6.4
-
-    The ``peer_fingerprint`` option was introduced in Symfony 6.4.
-
 Overriding default SMTP authenticators
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -373,11 +350,6 @@ This can be done from ``EsmtpTransport`` constructor or using the
     // Option 2: call a method to redefine the authenticators
     $transport->setAuthenticators([new XOAuth2Authenticator()]);
 
-.. versionadded:: 6.3
-
-    The ``$authenticators`` constructor parameter and the ``setAuthenticators()``
-    method were introduced in Symfony 6.3.
-
 Other Options
 ~~~~~~~~~~~~~
 
@@ -413,10 +385,6 @@ Other Options
 
         $dsn = 'smtps://smtp.example.com?max_per_second=2'
 
-    .. versionadded:: 6.2
-
-        The ``max_per_second`` option was introduced in Symfony 6.2.
-
 Creating & Sending Messages
 ---------------------------
 
@@ -816,11 +784,6 @@ for Twig templates::
         ])
     ;
 
-.. versionadded:: 6.4
-
-    The :method:`Symfony\\Bridge\\Twig\\Mime\\TemplatedEmail::locale` method
-    was introduced in Symfony 6.4.
-
 Then, create the template:
 
 .. code-block:: html+twig
@@ -1414,11 +1377,6 @@ the "rendering" of the email (computed headers, body rendering, ...) is also
 deferred and will only happen just before the email is sent by the Messenger
 handler.
 
-.. versionadded:: 6.2
-
-    The following example about rendering the email before calling
-    ``$mailer->send($email)`` works as of Symfony 6.2.
-
 When sending an email asynchronously, its instance must be serializable.
 This is always the case for :class:`Symfony\\Bridge\\Twig\\Mime\\Email`
 instances, but when sending a
@@ -1492,11 +1450,6 @@ disable asynchronous delivery.
     an open connection to the SMTP server in between sending emails.
     You can do so by using the ``stop()`` method.
 
-.. versionadded:: 6.1
-
-    The :method:`Symfony\\Component\\Mailer\\Transport\\Smtp\\SmtpTransport::stop`
-    method was made public in Symfony 6.1.
-
 You can also select the transport by adding an ``X-Bus-Transport`` header (which
 will be removed automatically from the final message)::
 
@@ -1504,10 +1457,6 @@ will be removed automatically from the final message)::
     $email->getHeaders()->addTextHeader('X-Bus-Transport', 'app.another_bus');
     $mailer->send($email);
 
-.. versionadded:: 6.2
-
-    The ``X-Bus-Transport`` header support was introduced in Symfony 6.2.
-
 Adding Tags and Metadata to Emails
 ----------------------------------
 
@@ -1549,17 +1498,9 @@ The following transports only support metadata:
 * Amazon SES (note that Amazon refers to this feature as "tags", but Symfony
   calls it "metadata" because it contains a key and a value)
 
-.. versionadded:: 6.1
-
-    Metadata support for Amazon SES was introduced in Symfony 6.1.
-
 Draft Emails
 ------------
 
-.. versionadded:: 6.1
-
-    ``Symfony\Component\Mime\DraftEmail`` was introduced in 6.1.
-
 :class:`Symfony\\Component\\Mime\\DraftEmail` is a special instance of
 :class:`Symfony\\Component\\Mime\\Email`. Its purpose is to build up an email
 (with body, attachments, etc) and make available to download as an ``.eml`` with
@@ -1631,10 +1572,6 @@ the email is sent::
         $event->addStamp(new SomeMessengerStamp());
     }
 
-.. versionadded:: 6.2
-
-    Methods ``addStamp()`` and ``getStamps()`` were introduced in Symfony 6.2.
-
 If you want to stop the Message from being sent, call ``reject()`` (it will
 also stop the event propagation)::
 
@@ -1645,10 +1582,6 @@ also stop the event propagation)::
         $event->reject();
     }
 
-.. versionadded:: 6.3
-
-    The ``reject()`` method was introduced in Symfony 6.3.
-
 Execute this command to find out which listeners are registered for this event
 and their priorities:
 
@@ -1661,10 +1594,6 @@ SentMessageEvent
 
 **Event Class**: :class:`Symfony\\Component\\Mailer\\Event\\SentMessageEvent`
 
-.. versionadded:: 6.2
-
-    The ``SentMessageEvent`` event was introduced in Symfony 6.2.
-
 ``SentMessageEvent`` allows you to act on the :class:`Symfony\\Component\\\Mailer\\\SentMessage`
 class to access the original message (``getOriginalMessage()``) and some debugging
 information (``getDebug()``) such as the HTTP calls made by the HTTP transports,
@@ -1696,10 +1625,6 @@ FailedMessageEvent
 
 **Event Class**: :class:`Symfony\\Component\\Mailer\\Event\\FailedMessageEvent`
 
-.. versionadded:: 6.2
-
-    The ``FailedMessageEvent`` event was introduced in Symfony 6.2.
-
 ``FailedMessageEvent`` allows acting on the the initial message in case of a failure::
 
     use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -1749,10 +1674,6 @@ to test if sending emails works correctly:
 This command bypasses the :doc:`Messenger bus </messenger>`, if configured, to
 ease testing emails even when the Messenger consumer is not running.
 
-.. versionadded:: 6.2
-
-    The ``mailer:test`` command was introduced in Symfony 6.2.
-
 Disabling Delivery
 ~~~~~~~~~~~~~~~~~~
 
diff --git a/messenger.rst b/messenger.rst
index 39200f0cb70..1322841c974 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -71,10 +71,6 @@ message class (or a message interface)::
     methods. You may use the attribute on as many methods in a single class as you
     like, allowing you to group the handling of multiple related types of messages.
 
-.. versionadded:: 6.1
-
-    Support for ``#[AsMessageHandler]`` on methods was introduced in Symfony 6.1.
-
 Thanks to :ref:`autoconfiguration <services-autoconfigure>` and the ``SmsNotification``
 type-hint, Symfony knows that this handler should be called when an ``SmsNotification``
 message is dispatched. Most of the time, this is all you need to do. But you can
@@ -349,11 +345,6 @@ to multiple transports:
     name as its only argument. For more information about stamps, see
     `Envelopes & Stamps`_.
 
-.. versionadded:: 6.2
-
-    The :class:`Symfony\\Component\\Messenger\\Stamp\\TransportNamesStamp`
-    stamp was introduced in Symfony 6.2.
-
 Doctrine Entities in Messages
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -684,10 +675,6 @@ of some or all transports:
     In order for this command to work, the configured transport's receiver must implement
     :class:`Symfony\\Component\\Messenger\\Transport\\Receiver\\MessageCountAwareInterface`.
 
-.. versionadded:: 6.2
-
-    The ``messenger:stats`` command was introduced in Symfony 6.2.
-
 .. _messenger-supervisor:
 
 Supervisor Configuration
@@ -769,10 +756,6 @@ However, you might prefer to use different POSIX signals for graceful shutdown.
 You can override default ones by setting the ``framework.messenger.stop_worker_on_signals``
 configuration option.
 
-.. versionadded:: 6.3
-
-    The ``framework.messenger.stop_worker_on_signals`` option was introduced in Symfony 6.3.
-
 In some cases the ``SIGTERM`` signal is sent by Supervisor itself (e.g. stopping
 a Docker container having Supervisor as its entrypoint). In these cases you
 need to add a ``stopwaitsecs`` key to the program configuration (with a value
@@ -985,10 +968,6 @@ this is configurable for each transport:
     the serialized form of the message is saved, which prevents to serialize it
     again if the message is later retried.
 
-    .. versionadded:: 6.1
-
-        The ``SerializedMessageStamp`` class was introduced in Symfony 6.1.
-
 Avoiding Retrying
 ~~~~~~~~~~~~~~~~~
 
@@ -1105,15 +1084,6 @@ to retry them:
     # remove all messages in the failure transport
     $ php bin/console messenger:failed:remove --all
 
-.. versionadded:: 6.2
-
-    The ``--class-filter`` and ``--stats`` options were introduced in Symfony 6.2.
-
-.. versionadded:: 6.4
-
-    The ``--all`` option was introduced in Symfony 6.4.
-
-
 If the message fails again, it will be re-sent back to the failure transport
 due to the normal :ref:`retry rules <messenger-retries-failures>`. Once the max
 retry has been hit, the message will be discarded permanently.
@@ -1389,10 +1359,6 @@ The transport has a number of options:
 ``exchange[type]``                            Type of exchange                                   ``fanout``
 ============================================  =================================================  ===================================
 
-.. versionadded:: 6.1
-
-    The ``connection_name`` option was introduced in Symfony 6.1.
-
 You can also configure AMQP-specific settings on your message by adding
 :class:`Symfony\\Component\\Messenger\\Bridge\\Amqp\\Transport\\AmqpStamp` to
 your Envelope::
@@ -1615,15 +1581,6 @@ sentinel_master          String, if null or empty Sentinel      null
                          support is disabled
 =======================  =====================================  =================================
 
-.. versionadded:: 6.1
-
-    The ``persistent_id``, ``retry_interval``, ``read_timeout``, ``timeout``, and
-    ``sentinel_master`` options were introduced in Symfony 6.1.
-
-.. versionadded:: 6.4
-
-    Support for the multiple Redis Sentinel hosts DNS was introduced in Symfony 6.4.
-
 .. caution::
 
     There should never be more than one ``messenger:consume`` command running with the same
@@ -1782,10 +1739,6 @@ The transport has a number of options:
 ``wait_time``           `Long polling`_ duration in seconds     20
 ======================  ======================================  ===================================
 
-.. versionadded:: 6.1
-
-    The ``session_token`` option was introduced in Symfony 6.1.
-
 .. note::
 
     The ``wait_time`` parameter defines the maximum duration Amazon SQS should
@@ -1929,12 +1882,6 @@ contains many useful information such as the exit code or the output of the
 process. You can refer to the page dedicated on
 :ref:`handler results <messenger-getting-handler-results>` for more information.
 
-.. versionadded:: 6.4
-
-    The :class:`Symfony\\Component\\Console\\Messenger\\RunCommandMessage`
-    and :class:`Symfony\\Component\\Console\\Messenger\\RunCommandContext`
-    classes were introduced in Symfony 6.4.
-
 Trigger An External Process
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -1967,12 +1914,6 @@ contains many useful information such as the exit code or the output of the
 process. You can refer to the page dedicated on
 :ref:`handler results <messenger-getting-handler-results>` for more information.
 
-.. versionadded:: 6.4
-
-    The :class:`Symfony\\Component\\Process\\Messenger\\RunProcessMessage`
-    and :class:`Symfony\\Component\\Process\\Messenger\\RunProcessContext`
-    classes were introduced in Symfony 6.4.
-
 Pinging A Webservice
 --------------------
 
@@ -2013,11 +1954,6 @@ The handler will return a
 :class:`Symfony\\Contracts\\HttpClient\\ResponseInterface`, allowing you to
 gather and process information returned by the HTTP request.
 
-.. versionadded:: 6.4
-
-    The :class:`Symfony\\Component\\HttpClient\\Messenger\\PingWebhookMessage`
-    class was introduced in Symfony 6.4.
-
 Getting Results from your Handlers
 ----------------------------------
 
@@ -2538,11 +2474,6 @@ provided in order to ease the declaration of these special handlers::
         }
     }
 
-.. versionadded:: 6.3
-
-    The :method:`Symfony\\Component\\Messenger\\Handler\\BatchHandlerTrait::getBatchSize`
-    method was introduced in Symfony 6.3.
-
 .. note::
 
     When the ``$ack`` argument of ``__invoke()`` is ``null``, the message is
@@ -2868,10 +2799,6 @@ of the process. For each, the event class is the event name:
 * :class:`Symfony\\Component\\Messenger\\Event\\WorkerStartedEvent`
 * :class:`Symfony\\Component\\Messenger\\Event\\WorkerStoppedEvent`
 
-.. versionadded:: 6.2
-
-    The ``WorkerRateLimitedEvent`` was introduced in Symfony 6.2.
-
 Additional Handler Arguments
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -2920,11 +2847,6 @@ Then your handler will look like this::
         }
     }
 
-.. versionadded:: 6.2
-
-    The :class:`Symfony\\Component\\Messenger\\Stamp\\HandlerArgumentsStamp`
-    was introduced in Symfony 6.2.
-
 .. _messenger-multiple-buses:
 
 Multiple Buses, Command & Event Buses
@@ -3038,10 +2960,6 @@ an **event bus**. The event bus could have zero or more subscribers.
             $eventBus->middleware()->id('validation');
         };
 
-.. versionadded:: 6.2
-
-    The ``allow_no_senders`` option was introduced in Symfony 6.2.
-
 This will create three new services:
 
 * ``command.bus``: autowireable with the :class:`Symfony\\Component\\Messenger\\MessageBusInterface`
@@ -3247,12 +3165,6 @@ will take care of this message to redispatch it through the same bus it was
 dispatched at first. You can also use the second argument of the ``RedispatchMessage``
 constructor to provide transports to use when redispatching the message.
 
-.. versionadded:: 6.3
-
-    The :class:`Symfony\\Component\\Messenger\\Message\\RedispatchMessage`
-    and :class:`Symfony\\Component\\Messenger\\Handler\\RedispatchMessageHandler`
-    classes were introduced in Symfony 6.3.
-
 Learn more
 ----------
 
diff --git a/notifier.rst b/notifier.rst
index c617ea8224d..3127ec05bc1 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -102,26 +102,6 @@ Service             Package                                DSN
 `Yunpian`_          ``symfony/yunpian-notifier``           ``yunpian://APIKEY@default``
 ==================  =====================================  ===========================================================================
 
-.. versionadded:: 6.1
-
-    The 46elks, OrangeSms, KazInfoTeh and Sendberry integrations were introduced in Symfony 6.1.
-    The ``no_stop_clause`` option in ``OvhCloud`` DSN was introduced in Symfony 6.1.
-    The ``test`` option in ``Smsapi`` DSN was introduced in Symfony 6.1.
-
-.. versionadded:: 6.2
-
-    The ContactEveryone and SMSFactor integrations were introduced in Symfony 6.2.
-
-.. versionadded:: 6.3
-
-    The Bandwith, iSendPro, Plivo, RingCentral, SimpleTextin and Termii integrations
-    were introduced in Symfony 6.3.
-    The ``from`` option in ``Smsapi`` DSN is optional since Symfony 6.3.
-
-.. versionadded:: 6.4
-
-    The `Redlink`_ and `Brevo`_ integrations were introduced in Symfony 6.4.
-
 To enable a texter, add the correct DSN in your ``.env`` file and
 configure the ``texter_transports``:
 
@@ -211,14 +191,6 @@ send SMS messages::
         }
     }
 
-.. versionadded:: 6.2
-
-    The 3rd argument of ``SmsMessage`` (``$from``) was introduced in Symfony 6.2.
-
-.. versionadded:: 6.3
-
-    The 4th argument of ``SmsMessage`` (``$options``) was introduced in Symfony 6.3.
-
 The ``send()`` method returns a variable of type
 :class:`Symfony\\Component\\Notifier\\Message\\SentMessage` which provides
 information such as the message ID and the original message contents.
@@ -263,14 +235,6 @@ Service                                  Package                               D
 `Zulip`_                                 ``symfony/zulip-notifier``            ``zulip://EMAIL:TOKEN@HOST?channel=CHANNEL``
 ======================================   ====================================  =============================================================================
 
-.. versionadded:: 6.2
-
-    The Zendesk and Chatwork integration were introduced in Symfony 6.2.
-
-.. versionadded:: 6.3
-
-    The LINE Notify, Mastodon and Twitter integrations were introduced in Symfony 6.3.
-
 Chatters are configured using the ``chatter_transports`` setting:
 
 .. code-block:: bash
@@ -450,18 +414,6 @@ Service          Package                               DSN
 `Pushover`_      ``symfony/pushover-notifier``         ``pushover://USER_KEY:APP_TOKEN@default``
 ===============  ====================================  ==============================================================================
 
-.. versionadded:: 6.1
-
-    The Engagespot integration was introduced in Symfony 6.1.
-
-.. versionadded:: 6.3
-
-    The PagerDuty and Pushover integrations were introduced in Symfony 6.3.
-
-.. versionadded:: 6.4
-
-    The Novu, Ntfy and GoIP integrations were introduced in Symfony 6.4.
-
 To enable a texter, add the correct DSN in your ``.env`` file and
 configure the ``texter_transports``:
 
@@ -823,10 +775,6 @@ also exists to modify messages sent to those channels.
 Customize Browser Notifications (Flash Messages)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.1
-
-    Support for customizing importance levels was introduced in Symfony 6.1.
-
 The default behavior for browser channel notifications is to add a
 :ref:`flash message <flash-messages>` with ``notification`` as its key.
 
@@ -886,11 +834,6 @@ You can benefit from this class by using it directly or extending the
 
 See :ref:`testing documentation <notifier-assertions>` for the list of available assertions.
 
-.. versionadded:: 6.2
-
-    The :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\NotificationAssertionsTrait`
-    was introduced in Symfony 6.2.
-
 Disabling Delivery
 ------------------
 
diff --git a/performance.rst b/performance.rst
index 847da532769..1bb0e261c74 100644
--- a/performance.rst
+++ b/performance.rst
@@ -261,10 +261,6 @@ in performance, you can stop generating the file as follows:
         // ...
         $container->parameters()->set('debug.container.dump', false);
 
-.. versionadded:: 6.3
-
-    The ``debug.container.dump`` option was introduced in Symfony 6.3.
-
 .. _profiling-applications:
 
 Profiling Symfony Applications
diff --git a/profiler.rst b/profiler.rst
index b21132a5816..c0d3640109b 100644
--- a/profiler.rst
+++ b/profiler.rst
@@ -35,10 +35,6 @@ Symfony Profiler, which will look like this:
     in the ``X-Debug-Token-Link`` HTTP response header. Browse the ``/_profiler``
     URL to see all profiles.
 
-.. versionadded:: 6.3
-
-    Profile garbage collection was introduced in Symfony 6.3.
-
 .. note::
 
     To limit the storage used by profiles on disk, they are probabilistically
@@ -91,10 +87,6 @@ look for tokens based on some criteria::
     // gets the latest 10 tokens for requests that happened between 2 and 4 days ago
     $tokens = $profiler->find('', '', 10, '', '4 days ago', '2 days ago');
 
-.. versionadded:: 6.4
-
-    Prefixing the URL filter with a ``!`` symbol to negate the query was introduced in Symfony 6.4.
-
 Data Collectors
 ---------------
 
diff --git a/rate_limiter.rst b/rate_limiter.rst
index 1fe86ef020a..5cb5cbfd918 100644
--- a/rate_limiter.rst
+++ b/rate_limiter.rst
@@ -320,11 +320,6 @@ processes by reserving unused tokens.
             $limit->wait();
         } while (!$limit->isAccepted());
 
-.. versionadded:: 6.4
-
-    The support for the ``reserve()`` method for the ``SlidingWindow`` strategy
-    was introduced in Symfony 6.4.
-
 Exposing the Rate Limiter Status
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -370,11 +365,6 @@ the :class:`Symfony\\Component\\RateLimiter\\Reservation` object returned by the
         }
     }
 
-.. versionadded:: 6.4
-
-    The :method:`Symfony\\Component\\RateLimiter\\Policy\\SlidingWindow::calculateTimeForTokens`
-    method was introduced in Symfony 6.4.
-
 .. _rate-limiter-storage:
 
 Storing Rate Limiter State
diff --git a/reference/configuration/debug.rst b/reference/configuration/debug.rst
index 482396d2ae2..62cc40675b2 100644
--- a/reference/configuration/debug.rst
+++ b/reference/configuration/debug.rst
@@ -17,10 +17,6 @@ key in your application configuration.
     # environment variables with their actual values
     $ php bin/console debug:config --resolve-env framework
 
-.. versionadded:: 6.2
-
-    The ``--resolve-env`` option was introduced in Symfony 6.2.
-
 .. note::
 
     When using XML, you must use the ``http://symfony.com/schema/dic/debug``
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index aefbcac2fce..f31921cfc9c 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -60,10 +60,6 @@ thrown by the application and will turn them into HTTP responses.
 
 Starting from Symfony 7.0, the default value of this option will be ``true``.
 
-.. versionadded:: 6.2
-
-    The ``handle_all_throwables`` option was introduced in Symfony 6.2.
-
 .. _configuration-framework-http_cache:
 
 http_cache
@@ -124,10 +120,6 @@ skip_response_headers
 Set of response headers that will never be cached even when the response is cacheable
 and public.
 
-.. versionadded:: 6.3
-
-    The ``skip_response_headers`` option was introduced in Symfony 6.3.
-
 allow_reload
 ............
 
@@ -210,10 +202,6 @@ trust_x_sendfile_type_header
 
 **type**: ``boolean`` **default**: ``false``
 
-.. versionadded:: 6.1
-
-    The ``trust_x_sendfile_type_header`` option was introduced in Symfony 6.1.
-
 ``X-Sendfile`` is a special HTTP header that tells web servers to replace the
 response contents by the file that is defined in that header. This improves
 performance because files are no longer served by your application but directly
@@ -300,10 +288,6 @@ feature is to configure it on a system level. First, you can define this option
 in the ``SYMFONY_IDE`` environment variable, which Symfony reads automatically
 when ``framework.ide`` config is not set.
 
-.. versionadded:: 6.1
-
-    ``SYMFONY_IDE`` environment variable support was introduced in Symfony 6.1.
-
 Another alternative is to set the ``xdebug.file_link_format`` option in your
 ``php.ini`` configuration file. The format to use is the same as for the
 ``framework.ide`` option, but without the need to escape the percent signs
@@ -1016,10 +1000,6 @@ crypto_method
 The minimum version of TLS to accept. The value must be one of the
 ``STREAM_CRYPTO_METHOD_TLSv*_CLIENT`` constants defined by PHP.
 
-.. versionadded:: 6.3
-
-    The ``crypto_method`` option was introduced in Symfony 6.3.
-
 delay
 .....
 
@@ -1045,10 +1025,6 @@ extra
 Arbitrary additional data to pass to the HTTP client for further use.
 This can be particularly useful when :ref:`decorating an existing client <extensibility>`.
 
-.. versionadded:: 6.3
-
-    The ``extra`` option has been introduced in Symfony 6.3.
-
 .. _http-headers:
 
 headers
@@ -1263,10 +1239,6 @@ enough to be sure about the server, so you should combine this with the
 html_sanitizer
 ~~~~~~~~~~~~~~
 
-.. versionadded:: 6.1
-
-    The HTML sanitizer configuration was introduced in Symfony 6.1.
-
 The ``html_sanitizer`` option (and its children) are used to configure
 custom HTML sanitizers. Read more about the options in the
 :ref:`HTML sanitizer documentation <html-sanitizer-configuration>`.
@@ -1357,10 +1329,6 @@ Set this option to ``true`` to enable the serializer data collector and its
 profiler panel. When this option is ``true``, all normalizers and encoders are
 decorated by traceable implementations that collect profiling information about them.
 
-.. versionadded:: 6.1
-
-    The ``collect_serializer_data`` option was introduced in Symfony 6.1.
-
 rate_limiter
 ~~~~~~~~~~~~
 
@@ -1542,10 +1510,6 @@ cache_dir
 The directory where routing information will be cached. Can be set to
 ``~`` (``null``) to disable route caching.
 
-.. versionadded:: 6.2
-
-    The ``cache_dir`` setting was introduced in Symfony 6.2.
-
 secrets
 ~~~~~~~
 
@@ -3374,10 +3338,6 @@ Name of the lock you want to create.
 semaphore
 ~~~~~~~~~
 
-.. versionadded:: 6.1
-
-    The ``semaphore`` option was introduced in Symfony 6.1.
-
 **type**: ``string`` | ``array``
 
 The default semaphore adapter. Store's DSN are also allowed.
@@ -3824,10 +3784,6 @@ to the ``#[WithHttpStatus]`` attribute on the exception class::
     {
     }
 
-.. versionadded:: 6.3
-
-    The ``#[WithHttpStatus]`` attribute was introduced in Symfony 6.3.
-
 It is also possible to map a log level on a custom exception class using
 the ``#[WithLogLevel]`` attribute::
 
@@ -3841,10 +3797,6 @@ the ``#[WithLogLevel]`` attribute::
     {
     }
 
-.. versionadded:: 6.3
-
-    The ``#[WithLogLevel]`` attribute was introduced in Symfony 6.3.
-
 .. _`HTTP Host header attacks`: https://www.skeletonscribe.net/2013/05/practical-http-host-header-attacks.html
 .. _`Security Advisory Blog post`: https://symfony.com/blog/security-releases-symfony-2-0-24-2-1-12-2-2-5-and-2-3-3-released#cve-2013-4752-request-gethost-poisoning
 .. _`PhpStormProtocol`: https://github.com/aik099/PhpStormProtocol
diff --git a/reference/configuration/kernel.rst b/reference/configuration/kernel.rst
index c6c0669d1a4..2bfa662db8c 100644
--- a/reference/configuration/kernel.rst
+++ b/reference/configuration/kernel.rst
@@ -25,11 +25,6 @@ method of the kernel class, which you can override to return a different value.
 You can also change the build directory by defining an environment variable
 named ``APP_BUILD_DIR`` whose value is the absolute path of the build folder.
 
-.. versionadded:: 6.4
-
-    The support of the ``APP_BUILD_DIR`` environment variable was introduced in
-    Symfony 6.4.
-
 ``kernel.bundles``
 ------------------
 
diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst
index d6ffd07f102..aaa862fd2f1 100644
--- a/reference/configuration/security.rst
+++ b/reference/configuration/security.rst
@@ -497,10 +497,6 @@ It's also possible to use ``*`` as a wildcard for all directives:
             ],
         ]);
 
-.. versionadded:: 6.3
-
-    The ``clear_site_data`` option was introduced in Symfony 6.3.
-
 invalidate_session
 ..................
 
@@ -541,10 +537,6 @@ Set this option to ``true`` to enable CSRF protection in the logout process
 using Symfony's default CSRF token manager. Set also the ``csrf_token_manager``
 option if you need to use a custom CSRF token manager.
 
-.. versionadded:: 6.2
-
-    The ``enable_csrf`` option was introduced in Symfony 6.2.
-
 csrf_parameter
 ..............
 
@@ -807,10 +799,6 @@ user_identifier
 
 **type**: ``string`` **default**: ``emailAddress``
 
-.. versionadded:: 6.3
-
-    The ``user_identifier`` option was introduced in Symfony 6.3.
-
 The value of this option tells Symfony which parameter to use to find the user
 identifier in the "distinguished name".
 
@@ -1013,10 +1001,6 @@ the session must not be used when authenticating users:
 Routes under this firewall will be :ref:`configured stateless <stateless-routing>`
 when they are not explicitly configured stateless or not.
 
-.. versionadded:: 6.3
-
-    Stateless firewall marking routes stateless was introduced in Symfony 6.3.
-
 User Checkers
 ~~~~~~~~~~~~~
 
diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst
index 78a895bb4b8..883b0b11eb7 100644
--- a/reference/configuration/twig.rst
+++ b/reference/configuration/twig.rst
@@ -57,11 +57,6 @@ called to determine the default escaping applied to the template.
 If the service defined in ``autoescape_service`` is invocable (i.e. it defines
 the `__invoke() PHP magic method`_) you can omit this option.
 
-.. versionadded:: 6.4
-
-    The feature to use invocable services to omit this option was introduced in
-    Symfony 6.4.
-
 base_template_class
 ~~~~~~~~~~~~~~~~~~~
 
@@ -155,10 +150,6 @@ file_name_pattern
 
 **type**: ``string`` or ``array`` of ``string`` **default**: ``[]``
 
-.. versionadded:: 6.1
-
-    The ``file_name_pattern`` option was introduced in Symfony 6.1.
-
 Some applications store their front-end assets in the same directory as Twig
 templates. The ``lint:twig`` command filters those files to only lint the ones
 that match the ``*.twig`` filename pattern.
@@ -289,10 +280,6 @@ html_to_text_converter
 
 **type**: ``string`` **default**: ````
 
-.. versionadded:: 6.2
-
-    The ``html_to_text_converter`` option was introduced in Symfony 6.2.
-
 The service implementing
 :class:`Symfony\\Component\\Mime\\HtmlToTextConverter\\HtmlToTextConverterInterface`
 that will be used to automatically create the text part of an email from its
diff --git a/reference/constraints/Cascade.rst b/reference/constraints/Cascade.rst
index bd6050add0b..3c99f423b0f 100644
--- a/reference/constraints/Cascade.rst
+++ b/reference/constraints/Cascade.rst
@@ -95,8 +95,4 @@ The ``groups`` option is not available for this constraint.
 This option can be used to exclude one or more properties from the
 cascade validation.
 
-.. versionadded:: 6.3
-
-    The ``exclude`` option was introduced in Symfony 6.3.
-
 .. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/Choice.rst b/reference/constraints/Choice.rst
index 8e3b11a01ce..cd30e888245 100644
--- a/reference/constraints/Choice.rst
+++ b/reference/constraints/Choice.rst
@@ -315,10 +315,6 @@ When this option is ``false``, the constraint checks that the given value is
 not one of the values defined in the ``choices`` option. In practice, it makes
 the ``Choice`` constraint behave like a ``NotChoice`` constraint.
 
-.. versionadded:: 6.2
-
-    The ``match`` option was introduced in Symfony 6.2.
-
 ``message``
 ~~~~~~~~~~~
 
diff --git a/reference/constraints/Email.rst b/reference/constraints/Email.rst
index 3f4207471c1..516d6d07dca 100644
--- a/reference/constraints/Email.rst
+++ b/reference/constraints/Email.rst
@@ -116,10 +116,6 @@ This option defines the pattern used to validate the email address. Valid values
   `egulias/email-validator`_ library (which is already installed when using
   :doc:`Symfony Mailer </mailer>`; otherwise, you must install it separately).
 
-.. versionadded:: 6.2
-
-   The ``html5-allow-no-tld`` mode was introduced in 6.2.
-
 .. tip::
 
     The possible values of this option are also defined as PHP constants of
diff --git a/reference/constraints/Expression.rst b/reference/constraints/Expression.rst
index 1f3b4dcdb7c..bf015d17573 100644
--- a/reference/constraints/Expression.rst
+++ b/reference/constraints/Expression.rst
@@ -127,10 +127,6 @@ about the :doc:`expression language syntax </reference/formats/expression_langua
 Alternatively, you can set the ``negate`` option to ``false`` in order to
 assert that the expression must return ``true`` for validation to fail.
 
-.. versionadded:: 6.2
-
-   The ``negate`` option was introduced in Symfony 6.2.
-
 .. sidebar:: Mapping the Error to a Specific Field
 
     You can also attach the constraint to a specific property and still validate
@@ -247,10 +243,6 @@ in your expression:
 You also have access to the ``is_valid()`` function in your expression. This function
 checks that the data passed to function doesn't raise any validation violation.
 
-.. versionadded:: 6.4
-
-    The ``is_valid()`` expression function was introduced in Symfony 6.4.
-
 .. include:: /reference/constraints/_groups-option.rst.inc
 
 ``message``
@@ -276,10 +268,6 @@ Parameter        Description
 
 If ``false``, the validation fails when expression returns ``true``.
 
-.. versionadded:: 6.2
-
-   The ``negate`` option was introduced in Symfony 6.2.
-
 .. include:: /reference/constraints/_payload-option.rst.inc
 
 ``values``
diff --git a/reference/constraints/File.rst b/reference/constraints/File.rst
index 1c12ce0f103..13aec13b0d5 100644
--- a/reference/constraints/File.rst
+++ b/reference/constraints/File.rst
@@ -156,10 +156,6 @@ see `Wikipedia: Binary prefix`_.
 
 **type**: ``array`` or ``string``
 
-.. versionadded:: 6.2
-
-    The ``extensions`` option was introduced in Symfony 6.2.
-
 If set, the validator will check that the extension and the media type
 (formerly known as MIME type) of the underlying file are equal to the given
 extension and associated media type (if a string) or exist in the collection
@@ -275,10 +271,6 @@ You can find a list of existing mime types on the `IANA website`_.
 
 **type**: ``integer`` **default**: ``null``
 
-.. versionadded:: 6.3
-
-    The ``filenameMaxLength`` was introduced in Symfony 6.3.
-
 If set, the validator will check that the filename of the underlying file
 doesn't exceed a certain length.
 
@@ -287,10 +279,6 @@ doesn't exceed a certain length.
 
 **type**: ``string`` **default**: ``The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less.``
 
-.. versionadded:: 6.3
-
-    The ``filenameTooLongMessage`` was introduced in Symfony 6.3.
-
 The message displayed if the filename of the file exceeds the limit set
 with the ``filenameMaxLength`` option.
 
@@ -307,10 +295,6 @@ Parameter                       Description
 
 **type**: ``string`` **default**: ``The extension of the file is invalid ({{ extension }}). Allowed extensions are {{ extensions }}.``
 
-.. versionadded:: 6.2
-
-    The ``extensionsMessage`` option was introduced in Symfony 6.2.
-
 The message displayed if the extension of the file is not a valid extension
 per the `extensions`_ option.
 
diff --git a/reference/constraints/Length.rst b/reference/constraints/Length.rst
index 4eed36347c6..5b7cb581db5 100644
--- a/reference/constraints/Length.rst
+++ b/reference/constraints/Length.rst
@@ -144,10 +144,6 @@ Can be one of the following constants of the
 * ``COUNT_GRAPHEMES``: Uses :phpfunction:`grapheme_strlen` counting the length of the string in
   graphemes, i.e. even emojis and ZWJ sequences of composed emojis count as 1 character.
 
-.. versionadded:: 6.3
-
-    The ``countUnit`` option was introduced in Symfony 6.3.
-
 ``exactly``
 ~~~~~~~~~~~
 
@@ -180,10 +176,6 @@ Parameter               Description
 ``{{ value_length }}``  The current value's length
 ======================  ============================================================
 
-.. versionadded:: 6.3
-
-    The `{{ value_length }}` parameter was introduced in Symfony 6.3.
-
 .. include:: /reference/constraints/_groups-option.rst.inc
 
 ``max``
@@ -214,10 +206,6 @@ Parameter               Description
 ``{{ value_length }}``  The current value's length
 ======================  ============================================================
 
-.. versionadded:: 6.3
-
-    The `{{ value_length }}` parameter was introduced in Symfony 6.3.
-
 ``min``
 ~~~~~~~
 
@@ -250,10 +238,6 @@ Parameter               Description
 ``{{ value_length }}``  The current value's length
 ======================  ============================================================
 
-.. versionadded:: 6.3
-
-    The `{{ value_length }}` parameter was introduced in Symfony 6.3.
-
 .. include:: /reference/constraints/_normalizer-option.rst.inc
 
 .. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/NoSuspiciousCharacters.rst b/reference/constraints/NoSuspiciousCharacters.rst
index cfc23141553..00e28cd6da1 100644
--- a/reference/constraints/NoSuspiciousCharacters.rst
+++ b/reference/constraints/NoSuspiciousCharacters.rst
@@ -1,10 +1,6 @@
 NoSuspiciousCharacters
 ======================
 
-.. versionadded:: 6.3
-
-    The ``NoSuspiciousCharacters`` constraint was introduced in Symfony 6.3.
-
 Validates that the given string does not contain characters used in spoofing
 security attacks, such as invisible characters such as zero-width spaces or
 characters that are visually similar.
diff --git a/reference/constraints/PasswordStrength.rst b/reference/constraints/PasswordStrength.rst
index 10a19b342d6..5e1d737c524 100644
--- a/reference/constraints/PasswordStrength.rst
+++ b/reference/constraints/PasswordStrength.rst
@@ -1,10 +1,6 @@
 PasswordStrength
 ================
 
-.. versionadded:: 6.3
-
-    The ``PasswordStrength`` constraint was introduced in Symfony 6.3.
-
 Validates that the given password has reached the minimum strength required by
 the constraint. The strengh of the password is not evaluated with a set of
 predefined rules (include a number, use lowercase and uppercase characters,
diff --git a/reference/constraints/Regex.rst b/reference/constraints/Regex.rst
index cd9d8c1ce45..bc042e1eb86 100644
--- a/reference/constraints/Regex.rst
+++ b/reference/constraints/Regex.rst
@@ -272,10 +272,6 @@ Parameter          Description
 ``{{ pattern }}``  The expected matching pattern
 =================  ==============================================================
 
-.. versionadded:: 6.3
-
-   The ``{{ pattern }}`` parameter was introduced in 6.3.
-
 ``pattern``
 ~~~~~~~~~~~
 
diff --git a/reference/constraints/Time.rst b/reference/constraints/Time.rst
index 1732fb584f0..6d4de73398f 100644
--- a/reference/constraints/Time.rst
+++ b/reference/constraints/Time.rst
@@ -115,8 +115,4 @@ Option     Pattern                          Correct value   Incorrect value
 ``false``  ``/^(\d{2}):(\d{2})$/``          ``12:00``       ``12:00:00``
 =========  ===============================  ==============  ================
 
-.. versionadded:: 6.4
-
-    The ``withSeconds`` option was introduced in Symfony 6.4.
-
 .. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/Type.rst b/reference/constraints/Type.rst
index f10d1423997..1bb4035c7fd 100644
--- a/reference/constraints/Type.rst
+++ b/reference/constraints/Type.rst
@@ -214,9 +214,5 @@ Finally, you can use aggregated functions:
 * ``finite-float``: ``is_float && is_finite``
 * ``finite-number``: ``is_int || is_float && is_finite``
 
-.. versionadded:: 6.4
-
-    ``number``, ``finite-float`` and ``finite-number`` were introduced in Symfony 6.4.
-
 .. _built-in PHP extension: https://www.php.net/book.ctype
 .. _a list of ctype functions: https://www.php.net/ref.ctype
diff --git a/reference/constraints/Unique.rst b/reference/constraints/Unique.rst
index 1f5631abc95..c7ee71329c4 100644
--- a/reference/constraints/Unique.rst
+++ b/reference/constraints/Unique.rst
@@ -96,10 +96,6 @@ Options
 **type**: ``array`` | ``string``
 
 
-.. versionadded:: 6.1
-
-    The ``fields`` option was introduced in Symfony 6.1.
-
 This is defines the key or keys in a collection that should be checked for
 uniqueness. By default, all collection keys are checked for uniqueness.
 
diff --git a/reference/constraints/UniqueEntity.rst b/reference/constraints/UniqueEntity.rst
index 3235f1ed4fb..ad7c09f1c31 100644
--- a/reference/constraints/UniqueEntity.rst
+++ b/reference/constraints/UniqueEntity.rst
@@ -361,11 +361,6 @@ this option to specify one or more fields to only ignore ``null`` values on them
     database, you might see insertion errors when your application attempts to
     persist entities that the ``UniqueEntity`` constraint considers valid.
 
-.. versionadded:: 6.3
-
-    The option to ignore ``null`` values for specific fields was introduced
-    in Symfony 6.3.
-
 ``message``
 ~~~~~~~~~~~
 
diff --git a/reference/constraints/Uuid.rst b/reference/constraints/Uuid.rst
index d8ff5fadb8b..c9f6c9741bf 100644
--- a/reference/constraints/Uuid.rst
+++ b/reference/constraints/Uuid.rst
@@ -129,15 +129,6 @@ you can also use the following PHP constants to refer to each UUID version:
 * ``Uuid::V7_MONOTONIC``
 * ``Uuid::V8_CUSTOM``
 
-.. versionadded:: 6.2
-
-    UUID versions 7 and 8 were introduced in Symfony 6.2.
-
-.. versionadded:: 6.4
-
-    Using a single integer instead of an integer array for this option
-    was introduced in Symfony 6.4.
-
 .. _`Universally unique identifier (UUID)`: https://en.wikipedia.org/wiki/Universally_unique_identifier
 .. _`RFC 4122`: https://tools.ietf.org/html/rfc4122
 .. _`UUID versions`: https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions
diff --git a/reference/constraints/When.rst b/reference/constraints/When.rst
index 144c1e3904c..e1e8ac895ce 100644
--- a/reference/constraints/When.rst
+++ b/reference/constraints/When.rst
@@ -1,10 +1,6 @@
 When
 ====
 
-.. versionadded:: 6.2
-
-    The ``When`` constraint was introduced in Symfony 6.2.
-
 This constraint allows you to apply constraints validation only if the
 provided expression returns true. See `Basic Usage`_ for an example.
 
@@ -275,10 +271,6 @@ You can also pass custom variables using the `values`_ option.
 
 One or multiple constraints that are applied if the expression returns true.
 
-.. versionadded:: 6.4
-
-    Passing a single ``Constraint`` instead of an array was introduced in Symfony 6.4.
-
 .. include:: /reference/constraints/_groups-option.rst.inc
 
 .. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/dic_tags.rst b/reference/dic_tags.rst
index 9983188c2ce..952705660c9 100644
--- a/reference/dic_tags.rst
+++ b/reference/dic_tags.rst
@@ -337,13 +337,6 @@ Value resolvers implement the
 and are used to resolve argument values for controllers as described here:
 :doc:`/controller/argument_value_resolver`.
 
-.. versionadded:: 6.2
-
-    The ``ValueResolverInterface`` was introduced in Symfony 6.2. Prior to
-    6.2, you had to use the
-    :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface`,
-    which defines different methods.
-
 data_collector
 --------------
 
diff --git a/reference/formats/expression_language.rst b/reference/formats/expression_language.rst
index a561ed5ce6d..dcd4d80aaec 100644
--- a/reference/formats/expression_language.rst
+++ b/reference/formats/expression_language.rst
@@ -21,11 +21,6 @@ The component supports:
 * **null** - ``null``
 * **exponential** - also known as scientific (e.g. ``1.99E+3`` or ``1e-2``)
 
-.. versionadded:: 6.1
-
-    Support for decimals without leading zeros and underscore separators were
-    introduced in Symfony 6.1.
-
 .. caution::
 
     A backslash (``\``) must be escaped by 4 backslashes (``\\\\``) in a string
@@ -114,10 +109,6 @@ operator)::
     $expressionLanguage->evaluate('fruit?.color', ['fruit' => '...'])
     $expressionLanguage->evaluate('fruit?.getStock()', ['fruit' => '...'])
 
-.. versionadded:: 6.1
-
-    The null safe operator was introduced in Symfony 6.1.
-
 .. _component-expression-functions:
 
 Working with Functions
@@ -176,10 +167,6 @@ This function will return the case of an enumeration::
 
 This will print out ``true``.
 
-.. versionadded:: 6.3
-
-    The ``enum()`` function was introduced in Symfony 6.3.
-
 .. tip::
 
     To read how to register your own functions to use in an expression, see
@@ -255,11 +242,6 @@ Comparison Operators
 * ``starts with``
 * ``ends with``
 
-.. versionadded:: 6.1
-
-    The ``contains``, ``starts with`` and ``ends with`` operators were introduced
-    in Symfony 6.1.
-
 .. tip::
 
     To test if a string does *not* match a regex, use the logical ``not``
diff --git a/reference/formats/yaml.rst b/reference/formats/yaml.rst
index 3130dd1d87b..64adac599fb 100644
--- a/reference/formats/yaml.rst
+++ b/reference/formats/yaml.rst
@@ -346,10 +346,6 @@ official YAML specification but are useful in Symfony applications:
           # ... or you can also use "->value" to directly use the value of a BackedEnum case
           operator_type: !php/enum App\Operator\Enum\Type::Or->value
 
-.. versionadded:: 6.2
-
-    The ``!php/enum`` tag was introduced in Symfony 6.2.
-
 Unsupported YAML Features
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/reference/forms/types/collection.rst b/reference/forms/types/collection.rst
index c18c558dbdc..d21802bbb91 100644
--- a/reference/forms/types/collection.rst
+++ b/reference/forms/types/collection.rst
@@ -200,10 +200,6 @@ prototype_options
 
 **type**: ``array`` **default**: ``[]``
 
-.. versionadded:: 6.1
-
-    The ``prototype_options`` option was introduced in Symfony 6.1.
-
 This is the array that's passed to the form type specified in the `entry_type`_
 option when creating its prototype. It allows to have different options depending
 on whether you are adding a new entry or editing an existing entry::
diff --git a/reference/forms/types/enum.rst b/reference/forms/types/enum.rst
index 12fdc125177..eb22715407f 100644
--- a/reference/forms/types/enum.rst
+++ b/reference/forms/types/enum.rst
@@ -80,10 +80,6 @@ implement ``TranslatableInterface`` to translate or display custom labels::
         }
     }
 
-.. versionadded:: 6.4
-
-    Support for ``TranslatableInterface`` was introduced in Symfony 6.4.
-
 Field Options
 -------------
 
diff --git a/reference/forms/types/number.rst b/reference/forms/types/number.rst
index 04a3676f7d4..77e685486a8 100644
--- a/reference/forms/types/number.rst
+++ b/reference/forms/types/number.rst
@@ -60,10 +60,6 @@ include an `inputmode HTML attribute`_ which depends on the value of this option
 If the ``scale`` value is ``0``, ``inputmode`` will be ``numeric``; if ``scale``
 is set to any value greater than ``0``, ``inputmode`` will be ``decimal``.
 
-.. versionadded:: 6.1
-
-   The automatic addition of the ``inputmode`` attribute was introduced in Symfony 6.1.
-
 Overridden Options
 ------------------
 
diff --git a/reference/forms/types/options/choice_label.rst.inc b/reference/forms/types/options/choice_label.rst.inc
index 0071498916f..3d83e44da52 100644
--- a/reference/forms/types/options/choice_label.rst.inc
+++ b/reference/forms/types/options/choice_label.rst.inc
@@ -29,12 +29,6 @@ more control::
         },
     ]);
 
-.. versionadded:: 6.2
-
-    Starting from Symfony 6.2, you can use any object that implements
-    :class:`Symfony\\Contracts\\Translation\\TranslatableInterface` as the value
-    of the choice label.
-
 This method is called for *each* choice, passing you the ``$choice`` and
 ``$key`` from the choices array (additional ``$value`` is related to `choice_value`_).
 This will give you:
diff --git a/reference/forms/types/options/duplicate_preferred_choices.rst.inc b/reference/forms/types/options/duplicate_preferred_choices.rst.inc
index 72e85067bd3..7569d54a21b 100644
--- a/reference/forms/types/options/duplicate_preferred_choices.rst.inc
+++ b/reference/forms/types/options/duplicate_preferred_choices.rst.inc
@@ -20,7 +20,3 @@ option to ``false``, to only display preferred choices at the top of the list::
         'preferred_choices' => ['muppets', 'arr'],
         'duplicate_preferred_choices' => false,
     ]);
-
-.. versionadded:: 6.4
-
-    The ``duplicate_preferred_choices`` option was introduced in Symfony 6.4.
diff --git a/reference/forms/types/options/help.rst.inc b/reference/forms/types/options/help.rst.inc
index 8c9bb5ce917..7d8fcdbec6b 100644
--- a/reference/forms/types/options/help.rst.inc
+++ b/reference/forms/types/options/help.rst.inc
@@ -19,8 +19,3 @@ rendered below the field::
             'help' => new TranslatableMessage('order.status', ['%order_id%' => $order->getId()], 'store'),
         ])
     ;
-
-.. versionadded:: 6.2
-
-    The support for ``TranslatableInterface`` objects as help contents was
-    introduced in Symfony 6.2.
diff --git a/reference/forms/types/options/placeholder_attr.rst.inc b/reference/forms/types/options/placeholder_attr.rst.inc
index 49b656cc6df..e537aae8922 100644
--- a/reference/forms/types/options/placeholder_attr.rst.inc
+++ b/reference/forms/types/options/placeholder_attr.rst.inc
@@ -15,7 +15,3 @@ Use this to add additional HTML attributes to the placeholder choice::
             ['title' => 'Choose an option'],
         ],
     ]);
-
-.. versionadded:: 6.3
-
-    The ``placeholder_attr`` option was introduced in Symfony 6.3.
diff --git a/reference/forms/types/options/sanitize_html.rst.inc b/reference/forms/types/options/sanitize_html.rst.inc
index d5525674815..1f906fd1354 100644
--- a/reference/forms/types/options/sanitize_html.rst.inc
+++ b/reference/forms/types/options/sanitize_html.rst.inc
@@ -3,10 +3,6 @@ sanitize_html
 
 **type**: ``boolean`` **default**: ``false``
 
-.. versionadded:: 6.1
-
-    The ``sanitize_html`` option was introduced in Symfony 6.1.
-
 When ``true``, the text input will be sanitized using the
 :doc:`Symfony HTML Sanitizer component </html_sanitizer>` after the form is
 submitted. This protects the form input against XSS, clickjacking and CSS
diff --git a/reference/forms/types/options/sanitizer.rst.inc b/reference/forms/types/options/sanitizer.rst.inc
index 66a76d591e7..39217653b3c 100644
--- a/reference/forms/types/options/sanitizer.rst.inc
+++ b/reference/forms/types/options/sanitizer.rst.inc
@@ -3,9 +3,5 @@ sanitizer
 
 **type**: ``string`` **default**: ``"default"``
 
-.. versionadded:: 6.1
-
-    The ``sanitizer`` option was introduced in Symfony 6.1.
-
 When `sanitize_html`_ is enabled, you can specify the name of a
 :ref:`custom sanitizer <html-sanitizer-configuration>` using this option.
diff --git a/reference/forms/types/password.rst b/reference/forms/types/password.rst
index d9b0f4cf066..d244a784755 100644
--- a/reference/forms/types/password.rst
+++ b/reference/forms/types/password.rst
@@ -37,10 +37,6 @@ entered into the box, set this to false and submit the form.
 
 **type**: ``string`` **default**: ``null``
 
-.. versionadded:: 6.2
-
-    The ``hash_property_path`` option was introduced in Symfony 6.2.
-
 If set, the password will be hashed using the
 :doc:`PasswordHasher component </security/passwords>` and stored in the
 property defined by the given :doc:`PropertyAccess expression </components/property_access>`.
diff --git a/reference/twig_reference.rst b/reference/twig_reference.rst
index 47b06ec2ea4..ef806adbc59 100644
--- a/reference/twig_reference.rst
+++ b/reference/twig_reference.rst
@@ -300,10 +300,6 @@ Generates a URL that you can visit to
 :doc:`impersonate a user </security/impersonating_user>`, identified by the
 ``identifier`` argument.
 
-.. versionadded:: 6.4
-
-    The ``impersonation_path()`` function was introduced in Symfony 6.4.
-
 impersonation_url
 ~~~~~~~~~~~~~~~~~
 
@@ -317,10 +313,6 @@ impersonation_url
 It's similar to the `impersonation_path`_ function, but it generates
 absolute URLs instead of relative URLs.
 
-.. versionadded:: 6.4
-
-    The ``impersonation_url()`` function was introduced in Symfony 6.4.
-
 impersonation_exit_path
 ~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -442,10 +434,6 @@ Translates the text into the current language. More information in
 sanitize_html
 ~~~~~~~~~~~~~
 
-.. versionadded:: 6.1
-
-    The ``sanitize_html()`` filter was introduced in Symfony 6.1.
-
 .. code-block:: twig
 
     {{ body|sanitize_html(sanitizer = "default") }}
diff --git a/routing.rst b/routing.rst
index fb5931cc517..8a75eb195cb 100644
--- a/routing.rst
+++ b/routing.rst
@@ -48,10 +48,6 @@ classes declared in the ``App\Controller`` namespace and stored in the
 act as a controller too, which is especially useful for small applications that
 use Symfony as a microframework.
 
-.. versionadded:: 6.2
-
-    The feature to import routes from a PSR-4 namespace root was introduced in Symfony 6.2.
-
 Suppose you want to define a route for the ``/blog`` URL in your application. To
 do so, create a :doc:`controller class </controller>` like the following:
 
@@ -374,10 +370,6 @@ can use any of these variables created by Symfony:
     An array of matched :ref:`route parameters <routing-route-parameters>` for
     the current route.
 
-.. versionadded:: 6.1
-
-    The ``params`` variable was introduced in Symfony 6.1.
-
 You can also use these functions:
 
 ``env(string $name)``
@@ -408,11 +400,6 @@ You can also use these functions:
         // Or without alias:
         #[Route(condition: "service('App\\\Service\\\RouteChecker').check(request)")]
 
-.. versionadded:: 6.1
-
-    The ``service(string $alias)`` function and ``#[AsRoutingConditionService]``
-    attribute were introduced in Symfony 6.1.
-
 Behind the scenes, expressions are compiled down to raw PHP. Because of this,
 using the ``condition`` key causes no extra overhead beyond the time it takes
 for the underlying PHP to execute.
@@ -467,10 +454,6 @@ route details:
     Use the ``--show-aliases`` option to show all available aliases for a given
     route.
 
-.. versionadded:: 6.4
-
-    The ``--show-aliases`` option was introduced in Symfony 6.4.
-
 The other command is called ``router:match`` and it shows which route will match
 the given URL. It's useful to find out why some URL is not executing the
 controller action that you expect:
@@ -664,10 +647,6 @@ URL                       Route          Parameters
     contains a collection of commonly used regular-expression constants such as
     digits, dates and UUIDs which can be used as route parameter requirements.
 
-    .. versionadded:: 6.1
-
-        The ``Requirement`` enum was introduced in Symfony 6.1.
-
 .. tip::
 
     Route requirements (and route paths too) can include
@@ -956,12 +935,6 @@ A common routing need is to convert the value stored in some parameter (e.g. an
 integer acting as the user ID) into another value (e.g. the object that
 represents the user). This feature is called a "param converter".
 
-.. versionadded:: 6.2
-
-    Starting from Symfony 6.2, route param conversion is a built-in feature.
-    In previous Symfony versions you had to install the package
-    ``sensio/framework-extra-bundle`` before using this feature.
-
 Now, keep the previous route configuration, but change the arguments of the
 controller action. Instead of ``string $slug``, add ``BlogPost $post``::
 
@@ -998,10 +971,6 @@ database queries used to fetch the object from the route parameter.
 Backed Enum Parameters
 ~~~~~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.3
-
-    The support of ``\BackedEnum`` as route parameters was introduced Symfony 6.3.
-
 You can use PHP `backed enumerations`_ as route parameters because Symfony will
 convert them automatically to their scalar values.
 
@@ -1622,13 +1591,6 @@ the current route and its attributes:
     {% set route_name = app.current_route %}
     {% set route_parameters = app.current_route_parameters %}
 
-.. versionadded:: 6.2
-
-    The ``app.current_route`` and ``app.current_route_parameters`` variables
-    were introduced in Symfony 6.2.
-    Before you had to access ``_route`` and ``_route_params`` request
-    attributes using ``app.request.attributes.get()``.
-
 Special Routes
 --------------
 
diff --git a/routing/custom_route_loader.rst b/routing/custom_route_loader.rst
index d02e6b31519..0cea7d6b9fd 100644
--- a/routing/custom_route_loader.rst
+++ b/routing/custom_route_loader.rst
@@ -108,15 +108,6 @@ Symfony provides several route loaders for the most common needs:
             $routes->import('@AcmeOtherBundle/Resources/config/routing/', 'directory');
         };
 
-.. versionadded:: 6.1
-
-    The ``attribute`` value of the second argument of ``import()`` was introduced
-    in Symfony 6.1.
-
-.. versionadded:: 6.2
-
-    The feature to import routes from a PSR-4 namespace root was introduced in Symfony 6.2.
-
 .. note::
 
     When importing resources, the key (e.g. ``app_file``) is the name of the collection.
diff --git a/security.rst b/security.rst
index 7285a6b77b4..9e40924cae3 100644
--- a/security.rst
+++ b/security.rst
@@ -468,12 +468,6 @@ You can also manually hash a password by running:
 Read more about all available hashers and password migration in
 :doc:`security/passwords`.
 
-.. versionadded:: 6.2
-
-    In applications using Symfony 6.2 and PHP 8.2 or newer, the
-    `SensitiveParameter PHP attribute`_ is applied to all plain passwords and
-    sensitive tokens so they don't appear in stack traces.
-
 .. _firewalls-authentication:
 .. _a-authentication-firewalls:
 
@@ -612,10 +606,6 @@ don't accidentally block Symfony's dev tools - which live under URLs like
 
     This feature is not supported by the XML configuration format.
 
-    .. versionadded:: 6.4
-
-        The feature to use an array of regex was introduced in Symfony 6.4.
-
 All *real* URLs are handled by the ``main`` firewall (no ``pattern`` key means
 it matches *all* URLs). A firewall can have many modes of authentication,
 in other words, it enables many ways to ask the question "Who are you?".
@@ -680,10 +670,6 @@ use the :class:`Symfony\\Bundle\\SecurityBundle\\Security` service::
         }
     }
 
-.. versionadded:: 6.2
-
-    The ``getFirewallConfig()`` method was introduced in Symfony 6.2.
-
 .. _security-authenticators:
 
 Authenticating Users
@@ -1717,17 +1703,6 @@ for more information about this.
 Login Programmatically
 ----------------------
 
-.. versionadded:: 6.2
-
-    The :class:`Symfony\Bundle\SecurityBundle\Security <Symfony\\Bundle\\SecurityBundle\\Security>`
-    class was introduced in Symfony 6.2. Prior to 6.2, it was called
-    ``Symfony\Component\Security\Core\Security``.
-
-.. versionadded:: 6.2
-
-    The :method:`Symfony\\Bundle\\SecurityBundle\\Security::login`
-    method was introduced in Symfony 6.2.
-
 You can log in a user programmatically using the ``login()`` method of the
 :class:`Symfony\\Bundle\\SecurityBundle\\Security` helper::
 
@@ -1769,14 +1744,6 @@ You can log in a user programmatically using the ``login()`` method of the
         }
     }
 
-.. versionadded:: 6.3
-
-    The feature to use a custom redirection logic was introduced in Symfony 6.3.
-
-.. versionadded:: 6.4
-
-    The feature to add badges was introduced in Symfony 6.4.
-
 .. _security-logging-out:
 
 Logging Out
@@ -1904,17 +1871,6 @@ Symfony will un-authenticate the current user and redirect them.
 Logout programmatically
 ~~~~~~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.2
-
-    The :class:`Symfony\Bundle\SecurityBundle\Security <Symfony\\Bundle\\SecurityBundle\\Security>`
-    class was introduced in Symfony 6.2. Prior to 6.2, it was called
-    ``Symfony\Component\Security\Core\Security``.
-
-.. versionadded:: 6.2
-
-    The :method:`Symfony\\Bundle\\SecurityBundle\\Security::logout`
-    method was introduced in Symfony 6.2.
-
 You can logout user programmatically using the ``logout()`` method of the
 :class:`Symfony\\Bundle\\SecurityBundle\\Security` helper::
 
@@ -2049,12 +2005,6 @@ If you need to get the logged in user from a service, use the
         }
     }
 
-.. versionadded:: 6.2
-
-    The :class:`Symfony\\Bundle\\SecurityBundle\\Security` class
-    was introduced in Symfony 6.2. In previous Symfony versions this class was
-    defined in ``Symfony\Component\Security\Core\Security``.
-
 Fetch the User in a Template
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -2454,15 +2404,6 @@ that is thrown with the ``exceptionCode`` argument::
         // ...
     }
 
-.. versionadded:: 6.2
-
-    The ``#[IsGranted()]`` attribute was introduced in Symfony 6.2.
-
-.. versionadded:: 6.3
-
-    The ``exceptionCode`` argument of the ``#[IsGranted()]`` attribute was
-    introduced in Symfony 6.3.
-
 .. _security-template:
 
 Access Control in Templates
@@ -2896,4 +2837,3 @@ Authorization (Denying Access)
 .. _`HTTP Basic authentication`: https://en.wikipedia.org/wiki/Basic_access_authentication
 .. _`Login CSRF attacks`: https://en.wikipedia.org/wiki/Cross-site_request_forgery#Forging_login_requests
 .. _`PHP date relative formats`: https://www.php.net/manual/en/datetime.formats.php#datetime.formats.relative
-.. _`SensitiveParameter PHP attribute`: https://www.php.net/manual/en/class.sensitiveparameter.php
diff --git a/security/access_control.rst b/security/access_control.rst
index abba217702f..4fd19925e85 100644
--- a/security/access_control.rst
+++ b/security/access_control.rst
@@ -33,14 +33,6 @@ options are used for matching:
 * ``attributes``: an array, which can be used to specify one or more :ref:`request attributes <accessing-request-data>` that must match exactly
 * ``route``: a route name
 
-.. versionadded:: 6.1
-
-    The ``request_matcher`` option was introduced in Symfony 6.1.
-
-.. versionadded:: 6.2
-
-    The ``route`` and ``attributes`` options were introduced in Symfony 6.2.
-
 Take the following ``access_control`` entries as an example:
 
 .. configuration-block::
diff --git a/security/access_token.rst b/security/access_token.rst
index b689949c71a..48ff8629fa1 100644
--- a/security/access_token.rst
+++ b/security/access_token.rst
@@ -352,10 +352,6 @@ an authorization server.
 1) Configure the OidcUserInfoTokenHandler
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.3
-
-    The ``OidcUserInfoTokenHandler`` class was introduced in Symfony 6.3.
-
 The ``OidcUserInfoTokenHandler`` requires the ``symfony/http-client`` package to
 make the needed HTTP requests. If you haven't installed it yet, run this command:
 
@@ -539,10 +535,6 @@ claims. To create your own user object from the claims, you must
 2) Configure the OidcTokenHandler
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.3
-
-    The ``OidcTokenHandler`` class was introduced in Symfony 6.3.
-
 The ``OidcTokenHandler`` requires ``web-token/jwt-signature``,
 ``web-token/jwt-checker`` and ``web-token/jwt-signature-algorithm-ecdsa``
 packages. If you haven't installed them yet, run these commands:
diff --git a/security/expressions.rst b/security/expressions.rst
index e3e6425f6d5..cf7071e79a9 100644
--- a/security/expressions.rst
+++ b/security/expressions.rst
@@ -69,10 +69,6 @@ and ``#[IsGranted()]`` attribute also accept an
             }
         }
 
-.. versionadded:: 6.2
-
-    The ``#[IsGranted()]`` attribute was introduced in Symfony 6.2.
-
 In this example, if the current user has ``ROLE_ADMIN`` or if the current
 user object's ``isSuperAdmin()`` method returns ``true``, then access will
 be granted (note: your User object may not have an ``isSuperAdmin()`` method,
diff --git a/security/impersonating_user.rst b/security/impersonating_user.rst
index b801b5570c1..8bc36c98c76 100644
--- a/security/impersonating_user.rst
+++ b/security/impersonating_user.rst
@@ -242,10 +242,6 @@ also adjust the query parameter name via the ``parameter`` setting:
 Redirecting to a Specific Target Route
 --------------------------------------
 
-.. versionadded:: 6.2
-
-    The ``target_route`` configuration option was introduced in Symfony 6.2.
-
 .. note::
 
     It works only in a stateful firewall.
diff --git a/security/login_link.rst b/security/login_link.rst
index 2af87ab4ded..041d59a1e1c 100644
--- a/security/login_link.rst
+++ b/security/login_link.rst
@@ -808,7 +808,3 @@ but you can change the lifetime per link using the third argument of the
     // the third optional argument is the lifetime in seconds
     $loginLinkDetails = $loginLinkHandler->createLoginLink($user, null, 60);
     $loginLink = $loginLinkDetails->getUrl();
-
-.. versionadded:: 6.2
-
-    The argument to customize the link lifetime was introduced in Symfony 6.2.
diff --git a/security/remember_me.rst b/security/remember_me.rst
index e2b087fa249..6d1e82e8c69 100644
--- a/security/remember_me.rst
+++ b/security/remember_me.rst
@@ -152,10 +152,6 @@ you can add a ``_remember_me`` key to the body of your POST request.
     Optionally, you can configure a custom name for this key using the
     ``name`` setting under the ``remember_me`` section of your firewall.
 
-.. versionadded:: 6.3
-
-    The JSON login ``_remember_me`` option was introduced in Symfony 6.3.
-
 Always activating Remember Me
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/security/user_checkers.rst b/security/user_checkers.rst
index 99cdfe04076..d62cc0bea32 100644
--- a/security/user_checkers.rst
+++ b/security/user_checkers.rst
@@ -117,10 +117,6 @@ is the service id of your user checker:
 Using Multiple User Checkers
 ----------------------------
 
-.. versionadded:: 6.2
-
-    The ``ChainUserChecker`` class was added in Symfony 6.2.
-
 It is common for applications to have multiple authentication entry points (such as
 traditional form based login and an API) which may have unique checker rules for each
 entry point as well as common rules for all entry points. To allow using multiple user
diff --git a/security/voters.rst b/security/voters.rst
index 7d37aea2510..0aefd3c2aa8 100644
--- a/security/voters.rst
+++ b/security/voters.rst
@@ -126,10 +126,6 @@ calls out to the "voter" system. Right now, no voters will vote on whether or no
 the user can "view" or "edit" a ``Post``. But you can create your *own* voter that
 decides this using whatever logic you want.
 
-.. versionadded:: 6.2
-
-    The ``#[IsGranted()]`` attribute was introduced in Symfony 6.2.
-
 Creating the custom Voter
 -------------------------
 
diff --git a/serializer.rst b/serializer.rst
index daa898dbb7b..ef155a1a45d 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -157,10 +157,6 @@ configuration:
             ;
         };
 
-.. versionadded:: 6.2
-
-    The option to configure YAML indentation was introduced in Symfony 6.2.
-
 You can also specify the context on a per-property basis::
 
 .. configuration-block::
@@ -267,19 +263,11 @@ all the properties of the class::
         // ...
     }
 
-.. versionadded:: 6.4
-
-    The ``#[Context]`` attribute was introduced in Symfony 6.4.
-
 .. _serializer-using-context-builders:
 
 Using Context Builders
 ----------------------
 
-.. versionadded:: 6.1
-
-    Context builders were introduced in Symfony 6.1.
-
 To define the (de)serialization context, you can use "context builders", which
 are objects that help you to create that context by providing autocompletion,
 validation, and documentation::
@@ -369,11 +357,6 @@ In this example, the ``id`` and the ``name`` properties belong to the
 ``show_product`` and ``list_product`` groups. The ``description`` property
 only belongs to the ``show_product`` group.
 
-.. versionadded:: 6.4
-
-    The support of the ``#[Groups]`` attribute on class level was
-    introduced in Symfony 6.4.
-
 Now that your groups are defined, you can choose which groups to use when
 serializing::
 
@@ -444,10 +427,6 @@ their paths using a :doc:`valid PropertyAccess syntax </components/property_acce
             </class>
         </serializer>
 
-.. versionadded:: 6.2
-
-    The option to configure a ``SerializedPath`` was introduced in Symfony 6.2.
-
 Using the configuration from above, denormalizing with a metadata-aware
 normalizer will write the ``birthday`` field from ``$data`` onto the ``Person``
 object::
@@ -551,11 +530,6 @@ given class:
         |          | ]                                                          |
         +----------+------------------------------------------------------------+
 
-.. versionadded:: 6.3
-
-    The debug:serializer`` command was introduced in Symfony 6.3.
-
-
 Going Further with the Serializer
 ---------------------------------
 
diff --git a/serializer/custom_context_builders.rst b/serializer/custom_context_builders.rst
index b40e432286d..a326fcfc2d6 100644
--- a/serializer/custom_context_builders.rst
+++ b/serializer/custom_context_builders.rst
@@ -1,10 +1,6 @@
 How to Create your Custom Context Builder
 =========================================
 
-.. versionadded:: 6.1
-
-    Context builders were introduced in Symfony 6.1.
-
 The :doc:`Serializer Component </components/serializer>` uses Normalizers
 and Encoders to transform any data to any data-structure (e.g. JSON).
 That serialization process can be configured thanks to a
diff --git a/service_container.rst b/service_container.rst
index c3e5c0b6860..47a60f37512 100644
--- a/service_container.rst
+++ b/service_container.rst
@@ -816,10 +816,6 @@ Our configuration looks like this:
     Closures can be injected :ref:`by using autowiring <autowiring_closures>`
     and its dedicated attributes.
 
-.. versionadded:: 6.1
-
-    The ``closure`` argument type was introduced in Symfony 6.1.
-
 .. _services-binding:
 
 Binding Arguments by Name or Type
@@ -1168,11 +1164,6 @@ key. For example, the default Symfony configuration contains this:
     may use the :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Exclude`
     attribute directly on your class to exclude it.
 
-    .. versionadded:: 6.3
-
-        The :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Exclude`
-        attribute was introduced in Symfony 6.3.
-
 This can be used to quickly make many classes available as services and apply some
 default configuration. The ``id`` of each service is its fully-qualified class name.
 You can override any service that's imported by using its id (class name) below
@@ -1451,11 +1442,6 @@ Thanks to the ``#[AutowireCallable]`` attribute, you can now inject this
         }
     }
 
-.. versionadded:: 6.3
-
-    The :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireCallable`
-    attribute was introduced in Symfony 6.3.
-
 Instead of using the ``#[AutowireCallable]`` attribute, you can also generate
 an adapter for a functional interface through configuration:
 
diff --git a/service_container/alias_private.rst b/service_container/alias_private.rst
index 7a7eef2a458..b74acb99d8e 100644
--- a/service_container/alias_private.rst
+++ b/service_container/alias_private.rst
@@ -150,10 +150,6 @@ services.
             $services->alias('app.mailer', PhpMailer::class);
         };
 
-.. versionadded:: 6.3
-
-    The ``#[AsAlias]`` attribute was introduced in Symfony 6.3.
-
 This means that when using the container directly, you can access the
 ``PhpMailer`` service by asking for the ``app.mailer`` service like this::
 
diff --git a/service_container/autowiring.rst b/service_container/autowiring.rst
index daa1e96328b..898ccdd100b 100644
--- a/service_container/autowiring.rst
+++ b/service_container/autowiring.rst
@@ -611,10 +611,6 @@ logic about those arguments::
         }
     }
 
-.. versionadded:: 6.1
-
-    The ``#[Autowire]`` attribute was introduced in Symfony 6.1.
-
 The ``#[Autowire]`` attribute can also be used for :ref:`parameters <service-parameters>`,
 :doc:`complex expressions </service_container/expression_language>` and even
 :ref:`environment variables <config-env-vars>`::
@@ -648,10 +644,6 @@ The ``#[Autowire]`` attribute can also be used for :ref:`parameters <service-par
         // ...
     }
 
-.. versionadded:: 6.3
-
-    The ``param`` and ``env`` arguments were introduced in Symfony 6.3.
-
 .. _autowiring_closures:
 
 Generate Closures With Autowiring
@@ -707,11 +699,6 @@ attribute::
         }
     }
 
-.. versionadded:: 6.3
-
-    The :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireServiceClosure`
-    attribute was introduced in Symfony 6.3.
-
 It is common that a service accepts a closure with a specific signature.
 In this case, you can use the
 :class:`Symfony\Component\DependencyInjection\Attribute\\AutowireCallable` attribute
@@ -748,11 +735,6 @@ attribute. By doing so, the callable will automatically be lazy, which means
 that the encapsulated service will be instantiated **only** at the
 closure's first call.
 
-.. versionadded:: 6.3
-
-    The :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireCallable`
-    attribute was introduced in Symfony 6.3.
-
 .. _autowiring-calls:
 
 Autowiring other Methods (e.g. Setters and Public Typed Properties)
diff --git a/service_container/debug.rst b/service_container/debug.rst
index e8f0022f1a2..c09413e7213 100644
--- a/service_container/debug.rst
+++ b/service_container/debug.rst
@@ -32,7 +32,7 @@ Partial search is also available:
 .. code-block:: terminal
 
     $ php bin/console debug:container --tag=kernel
-    
+
     Select one of the following tags to display its information:
      [0] kernel.event_listener
      [1] kernel.event_subscriber
@@ -42,10 +42,6 @@ Partial search is also available:
      [5] kernel.fragment_renderer
      [6] kernel.cache_clearer
 
-.. versionadded:: 6.2
-
-    The partial search was introduced in Symfony 6.2.
-
 Detailed Info about a Single Service
 ------------------------------------
 
diff --git a/service_container/expression_language.rst b/service_container/expression_language.rst
index 7847a87b3b8..41c538db468 100644
--- a/service_container/expression_language.rst
+++ b/service_container/expression_language.rst
@@ -76,10 +76,6 @@ In this context, you have access to 3 functions:
 ``env``
     Returns the value of an env variable.
 
-.. versionadded:: 6.1
-
-    The ``env()`` function was introduced in Symfony 6.1.
-
 You also have access to the :class:`Symfony\\Component\\DependencyInjection\\Container`
 via a ``container`` variable. Here's another example:
 
@@ -126,7 +122,3 @@ via a ``container`` variable. Here's another example:
 Expressions can be used in ``arguments``, ``properties``, as arguments with
 ``configurator``, as arguments to ``calls`` (method calls) and in
 ``factories`` (:doc:`service factories </service_container/factories>`).
-
-.. versionadded:: 6.1
-
-    Using expressions in ``factories`` was introduced in Symfony 6.1.
diff --git a/service_container/factories.rst b/service_container/factories.rst
index a917a661afa..d4357cfd58a 100644
--- a/service_container/factories.rst
+++ b/service_container/factories.rst
@@ -231,10 +231,6 @@ as the factory class:
                 ->constructor('create');
         };
 
-.. versionadded:: 6.3
-
-    The ``constructor`` option was introduced in Symfony 6.3.
-
 Non-Static Factories
 --------------------
 
@@ -377,10 +373,6 @@ method name:
 Using Expressions in Service Factories
 --------------------------------------
 
-.. versionadded:: 6.1
-
-    Using expressions as factories was introduced in Symfony 6.1.
-
 Instead of using PHP classes as a factory, you can also use
 :doc:`expressions </service_container/expression_language>`. This allows you to
 e.g. change the service based on a parameter:
diff --git a/service_container/lazy_services.rst b/service_container/lazy_services.rst
index 905c4b3a599..46e939d4fac 100644
--- a/service_container/lazy_services.rst
+++ b/service_container/lazy_services.rst
@@ -29,11 +29,6 @@ until you interact with the proxy in some way.
     In PHP versions prior to 8.0 lazy services do not support parameters with
     default values for built-in PHP classes (e.g. ``PDO``).
 
-.. versionadded:: 6.2
-
-    Starting from Symfony 6.2, service laziness is supported out of the box
-    without having to install any additional package.
-
 .. _lazy-services_configuration:
 
 Configuration
@@ -129,11 +124,6 @@ laziness, and supports lazy-autowiring of intersection types::
     ) {
     }
 
-.. versionadded:: 6.3
-
-    The ``lazy`` argument of the ``#[Autowire()]`` attribute was introduced in
-    Symfony 6.3.
-
 Interface Proxifying
 --------------------
 
diff --git a/service_container/service_decoration.rst b/service_container/service_decoration.rst
index 0262ae03e7e..ce33207e568 100644
--- a/service_container/service_decoration.rst
+++ b/service_container/service_decoration.rst
@@ -123,10 +123,6 @@ but keeps a reference of the old one as ``.inner``:
                 ->decorate(Mailer::class);
         };
 
-.. versionadded:: 6.1
-
-    The ``#[AsDecorator]`` attribute was introduced in Symfony 6.1.
-
 The ``decorates`` option tells the container that the ``App\DecoratingMailer``
 service replaces the ``App\Mailer`` service. If you're using the
 :ref:`default services.yaml configuration <service-container-services-load-example>`,
diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst
index a39ccfb4a68..a4aa426bc59 100644
--- a/service_container/service_subscribers_locators.rst
+++ b/service_container/service_subscribers_locators.rst
@@ -247,10 +247,6 @@ service type to a service.
 Add Dependency Injection Attributes
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.2
-
-    The ability to add attributes was introduced in Symfony 6.2.
-
 As an alternate to aliasing services in your configuration, you can also configure
 the following dependency injection attributes in the ``getSubscribedServices()``
 method directly:
@@ -375,12 +371,6 @@ attribute::
         }
     }
 
-.. versionadded:: 6.4
-
-    The
-    :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireLocator`
-    attribute was introduced in Symfony 6.4.
-
 .. note::
 
     To receive an iterable instead of a service locator, you can switch the
@@ -389,12 +379,6 @@ attribute::
     :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireIterator`
     attribute.
 
-    .. versionadded:: 6.4
-
-        The
-        :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireIterator`
-        attribute was introduced in Symfony 6.4.
-
 .. _service-subscribers-locators_defining-service-locator:
 
 Defining a Service Locator
@@ -939,10 +923,6 @@ and compose your services with them::
 ``SubscribedService`` Attributes
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.2
-
-    The ability to add attributes was introduced in Symfony 6.2.
-
 You can use the ``attributes`` argument of ``SubscribedService`` to add any
 of the following dependency injection attributes:
 
diff --git a/service_container/tags.rst b/service_container/tags.rst
index 4955016d5a0..5021ec3d8d5 100644
--- a/service_container/tags.rst
+++ b/service_container/tags.rst
@@ -550,10 +550,6 @@ To answer this, change the service declaration:
             ;
         };
 
-.. versionadded:: 6.2
-
-    Support for attributes as array was introduced in Symfony 6.2.
-
 .. tip::
 
     The ``name`` attribute is used by default to define the name of the tag.
@@ -847,15 +843,6 @@ iterator, add the ``exclude`` option:
     In the case the referencing service is itself tagged with the tag being used in the tagged
     iterator, it is automatically excluded from the injected iterable.
 
-.. versionadded:: 6.1
-
-    The ``exclude`` option was introduced in Symfony 6.1.
-
-.. versionadded:: 6.3
-
-    The automatic exclusion of the referencing service in the injected iterable was
-    introduced in Symfony 6.3.
-
 .. seealso::
 
     See also :doc:`tagged locator services </service_container/service_subscribers_locators>`
diff --git a/templates.rst b/templates.rst
index a8f066e83be..53edd5b89d8 100644
--- a/templates.rst
+++ b/templates.rst
@@ -385,19 +385,6 @@ gives you access to these variables:
 ``app.enabled_locales``
     The locales enabled in the application.
 
-.. versionadded:: 6.2
-
-    The ``app.current_route`` and ``app.current_route_parameters`` variables
-    were introduced in Symfony 6.2.
-
-.. versionadded:: 6.3
-
-    The ``app.locale`` variable was introduced in Symfony 6.3.
-
-.. versionadded:: 6.4
-
-    The ``app.enabled_locales`` variable was introduced in Symfony 6.4.
-
 In addition to the global ``app`` variable injected by Symfony, you can also
 inject variables automatically to all Twig templates as explained in the next
 section.
@@ -606,10 +593,6 @@ to define the template to render::
         }
     }
 
-.. versionadded:: 6.2
-
-    The ``#[Template()]`` attribute was introduced in Symfony 6.2.
-
 The :ref:`base AbstractController <the-base-controller-classes-services>` also provides the
 :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController::renderBlock`
 and :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController::renderBlockView`
@@ -649,13 +632,6 @@ This might come handy when dealing with blocks in
 :ref:`templates inheritance <template_inheritance-layouts>` or when using
 `Turbo Streams`_.
 
-.. versionadded:: 6.4
-
-    The
-    :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController::renderBlock` and
-    :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController::renderBlockView`
-    methods were introduced in Symfony 6.4.
-
 Rendering a Template in Services
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -907,10 +883,6 @@ depending on your needs:
         </a>
     {% endfor %}
 
-.. versionadded:: 6.3
-
-    The option to use named arguments in ``dump()`` was introduced in Symfony 6.3.
-
 To avoid leaking sensitive information, the ``dump()`` function/tag is only
 available in the ``dev`` and ``test`` :ref:`configuration environments <configuration-environments>`.
 If you try to use it in the ``prod`` environment, you will see a PHP error.
diff --git a/testing.rst b/testing.rst
index 6c61531e4ed..e5347efa841 100644
--- a/testing.rst
+++ b/testing.rst
@@ -320,11 +320,6 @@ concrete one::
 No further configuration in required, as the test service container is a special one
 that allows you to interact with private services and aliases.
 
-.. versionadded:: 6.3
-
-    The possibility to set a private service with the test service container
-    without declaring a public alias for it was introduced in Symfony 6.3.
-
 .. _testing-databases:
 
 Configuring a Database for Tests
@@ -726,12 +721,6 @@ attributes in this token, you can use the ``tokenAttributes`` argument of the
     By design, the ``loginUser()`` method doesn't work when using stateless firewalls.
     Instead, add the appropriate token/header in each ``request()`` call.
 
-.. versionadded:: 6.4
-
-    The ``tokenAttributes`` argument of the
-    :method:`Symfony\\Bundle\\FrameworkBundle\\KernelBrowser::loginUser` method
-    was introduced in Symfony 6.4.
-
 Making AJAX Requests
 ....................
 
@@ -997,11 +986,6 @@ Response Assertions
 ``assertResponseIsUnprocessable(string $message = '')``
     Asserts the response is unprocessable (HTTP status is 422)
 
-.. versionadded:: 6.4
-
-    The support for relative path in ``assertResponseRedirects()`` was introduced
-    in Symfony 6.4.
-
 Request Assertions
 ..................
 
@@ -1063,15 +1047,6 @@ Crawler Assertions
     Asserts that value of the field of the first form matching the given
     selector does (not) equal the expected value.
 
-.. versionadded:: 6.3
-
-    The ``assertSelectorCount()`` method was introduced in Symfony 6.3.
-
-.. versionadded:: 6.4
-
-    The ``assertAnySelectorTextContains()``, ``assertAnySelectorTextNotContains()``
-    and ``assertAnySelectorTextSame()`` were introduced in Symfony 6.4.
-
 .. _mailer-assertions:
 
 Mailer Assertions
@@ -1109,11 +1084,6 @@ Mailer Assertions
     Asserts that the subject of the given email does (not) contain the
     expected subject.
 
-.. versionadded:: 6.4
-
-    The ``assertEmailSubjectContains()`` and ``assertEmailSubjectNotContains()``
-    assertions were introduced in Symfony 6.4.
-
 Notifier Assertions
 ...................
 
@@ -1140,10 +1110,6 @@ Notifier Assertions
     Asserts that the name of the transport for the given notification
     is not the same as the given text.
 
-.. versionadded:: 6.2
-
-    The Notifier assertions were introduced in Symfony 6.2.
-
 HttpClient Assertions
 .....................
 
@@ -1167,10 +1133,6 @@ HttpClient Assertions
     By default it will check on the HttpClient, but you can also pass a specific
     HttpClient ID.
 
-.. versionadded:: 6.4
-
-    The HttpClient assertions were introduced in Symfony 6.4.
-
 .. TODO
 ..  End to End Tests (E2E)
 ..  ----------------------
diff --git a/translation.rst b/translation.rst
index 07f7cbde570..306b3186ad0 100644
--- a/translation.rst
+++ b/translation.rst
@@ -451,11 +451,6 @@ The ``translation:extract`` command looks for missing translations in:
 * Any PHP file/class stored in the ``src/`` directory that uses
   :ref:`Constraints Attributes <validation-constraints>`  with ``*message`` named argument(s).
 
-.. versionadded:: 6.2
-
-    The support of PHP files/classes that use constraint attributes was
-    introduced in Symfony 6.2.
-
 .. _translation-resource-locations:
 
 Translation Resource/File Names and Locations
@@ -499,10 +494,6 @@ provides many loaders which are selected based on the following file extensions:
 * ``.po``: `Portable object format`_;
 * ``.qt``: `QT Translations TS XML`_ file;
 
-.. versionadded:: 6.1
-
-    The ``.xliff`` file extension support was introduced in Symfony 6.1.
-
 The choice of which loader to use is entirely up to you and is a matter of
 taste. The recommended option is to use YAML for simple projects and use XLIFF
 if you're generating translations with specialized programs or teams.
@@ -607,10 +598,6 @@ Lokalise              ``composer require symfony/lokalise-translation-provider``
 Phrase                ``composer require symfony/phrase-translation-provider``
 ====================  ===========================================================
 
-.. versionadded:: 6.4
-
-    The ``Phrase`` translation provider was introduced in Symfony 6.4.
-
 Each library includes a :ref:`Symfony Flex recipe <symfony-flex>` that will add
 a configuration example to your ``.env`` file. For example, suppose you want to
 use Loco. First, install it:
@@ -766,11 +753,6 @@ now use the following commands to push (upload) and pull (download) translations
     # of flat keys
     $ php bin/console translation:pull loco --force --as-tree
 
-.. versionadded:: 6.4
-
-    The ``--as-tree`` option of the ``translation:pull`` command was introduced
-    in Symfony 6.4.
-
 Creating Custom Providers
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -1043,10 +1025,6 @@ checks translation resources for several locales:
 Switch Locale Programmatically
 ------------------------------
 
-.. versionadded:: 6.1
-
-    The ``LocaleSwitcher`` was introduced in Symfony 6.1.
-
 Sometimes you need to change the locale of the application dynamically
 just to run some code. Imagine a console command that renders Twig templates
 of emails in different languages. You need to change the locale only to
@@ -1103,13 +1081,6 @@ of:
         }
     }
 
-.. versionadded:: 6.4
-
-    The support of declaring an argument in the callback to inject the locale
-    being used in the
-    :method:`Symfony\\Component\\Translation\\LocaleSwitcher::runWithLocale`
-    method was introduced in Symfony 6.4.
-
 When using :ref:`autowiring <services-autowire>`, type-hint any controller or
 service argument with the :class:`Symfony\\Component\\Translation\\LocaleSwitcher`
 class to inject the locale switcher service. Otherwise, configure your services
diff --git a/validation.rst b/validation.rst
index af98a7ff852..39922038c9b 100644
--- a/validation.rst
+++ b/validation.rst
@@ -203,10 +203,6 @@ Inside the template, you can output the list of errors exactly as needed:
     object allows you, among other things, to get the constraint that caused this
     violation thanks to the ``ConstraintViolation::getConstraint()`` method.
 
-.. versionadded:: 6.3
-
-    The ``ConstraintViolation::getConstraint()`` method was introduced in Symfony 6.3.
-
 Validation Callables
 ~~~~~~~~~~~~~~~~~~~~
 
diff --git a/validation/custom_constraint.rst b/validation/custom_constraint.rst
index 7506cd84f2c..7ea504f0842 100644
--- a/validation/custom_constraint.rst
+++ b/validation/custom_constraint.rst
@@ -39,10 +39,6 @@ First you need to create a Constraint class and extend :class:`Symfony\\Componen
 Add ``#[\Attribute]`` to the constraint class if you want to
 use it as an attribute in other classes.
 
-.. versionadded:: 6.1
-
-    The ``#[HasNamedArguments]`` attribute was introduced in Symfony 6.1.
-
 You can use ``#[HasNamedArguments]`` to make some constraint options required::
 
     // src/Validator/ContainsAlphanumeric.php
diff --git a/workflow.rst b/workflow.rst
index 2e17b40794c..b1ec43c8199 100644
--- a/workflow.rst
+++ b/workflow.rst
@@ -168,11 +168,6 @@ follows:
     ``'draft'`` or ``!php/const App\Entity\BlogPost::TRANSITION_TO_REVIEW``
     instead of ``'to_review'``.
 
-.. versionadded:: 6.4
-
-    Since Symfony 6.4, the ``type`` option under ``marking_store`` can be
-    omitted when the ``property`` option is explicitly set.
-
 The configured property will be used via its implemented getter/setter methods by the marking store::
 
     // src/Entity/BlogPost.php
@@ -231,11 +226,6 @@ you must declare a setter to write your property::
         }
     }
 
-.. versionadded:: 6.4
-
-    The feature to use public properties instead of getter/setter methods
-    and private properties was introduced in Symfony 6.4.
-
 .. note::
 
     The marking store type could be "multiple_state" or "single_state". A single
@@ -342,16 +332,6 @@ attribute::
 This allows you to decorrelate the argument name of any implementation
 name.
 
-.. versionadded:: 6.2
-
-    All workflows and state machines services are tagged since in Symfony 6.2.
-
-.. versionadded:: 6.3
-
-    Injecting a workflow with only its name and
-    :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Target` was
-    introduced in Symfony 6.3.
-
 .. tip::
 
     If you want to retrieve all workflows, for documentation purposes for example,
@@ -548,10 +528,6 @@ You may refer to the documentation about
 :ref:`defining event listeners with PHP attributes <event-dispatcher_event-listener-attributes>`
 for further use.
 
-.. versionadded:: 6.4
-
-    The workflow event attributes were introduced in Symfony 6.4.
-
 .. _workflow-usage-guard-events:
 
 Guard Events
diff --git a/workflow/workflow-and-state-machine.rst b/workflow/workflow-and-state-machine.rst
index f6b93fa693c..eabb8d2a28e 100644
--- a/workflow/workflow-and-state-machine.rst
+++ b/workflow/workflow-and-state-machine.rst
@@ -283,10 +283,6 @@ machine type, use ``camelCased workflow name + StateMachine``::
     }
 
 
-.. versionadded:: 6.2
-
-    All workflows and state machines services are tagged since in Symfony 6.2.
-
 Automatic and Manual Validation
 -------------------------------
 

From 93a0effe629e49efce25f98f917d4119269b211f Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Sun, 22 Oct 2023 11:49:53 +0200
Subject: [PATCH 038/747] remove Symfony 6 versionadded directives

---
 components/finder.rst          | 4 ----
 components/http_foundation.rst | 6 ------
 html_sanitizer.rst             | 5 -----
 messenger.rst                  | 8 --------
 reference/dic_tags.rst         | 6 ------
 5 files changed, 29 deletions(-)

diff --git a/components/finder.rst b/components/finder.rst
index 6a76c73ac08..516db7cde4e 100644
--- a/components/finder.rst
+++ b/components/finder.rst
@@ -337,10 +337,6 @@ using a closure, return ``false`` for the directories which you want to prune.
 Pruning directories early can improve performance significantly depending on the
 file/directory hierarchy complexity and the number of excluded directories.
 
-.. versionadded:: 6.4
-
-    The feature to prune directories was introduced in Symfony 6.4.
-
 Sorting Results
 ---------------
 
diff --git a/components/http_foundation.rst b/components/http_foundation.rst
index 70060b93127..475d222dab5 100644
--- a/components/http_foundation.rst
+++ b/components/http_foundation.rst
@@ -478,12 +478,6 @@ your application to see which exceptions are thrown in listeners of the
 more about it in
 :ref:`the dedicated section about Kernel events <http-kernel-creating-listener>`.
 
-.. versionadded:: 6.4
-
-    The ``$flush`` parameter of the
-    :method:`Symfony\\Component\\HttpFoundation\\Response::send` method
-    was introduced in Symfony 6.4.
-
 Setting Cookies
 ~~~~~~~~~~~~~~~
 
diff --git a/html_sanitizer.rst b/html_sanitizer.rst
index 6dd9b7771cf..6a5195880c2 100644
--- a/html_sanitizer.rst
+++ b/html_sanitizer.rst
@@ -1008,11 +1008,6 @@ increase or decrease this limit:
 It is possible to disable this length limit by setting the max input length to
 ``-1``. Beware that it may expose your application to `DoS attacks`_.
 
-.. versionadded:: 6.4
-
-    The support for disabling the length limit of the HTML sanitizer was
-    introduced in Symfony 6.4.
-
 Custom Attribute Sanitizers
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/messenger.rst b/messenger.rst
index 3ee8b0dc6eb..9c8e8202afa 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1768,14 +1768,6 @@ The transport has a number of options:
     You can learn more about middlewares in
     :ref:`the dedicated section <messenger_middleware>`.
 
-    .. versionadded:: 6.4
-
-        The
-        :class:`Symfony\\Component\\Messenger\\Bridge\\AmazonSqs\\Middleware\\AddFifoStampMiddleware`,
-        :class:`Symfony\\Component\\Messenger\\Bridge\\AmazonSqs\\MessageDeduplicationAwareInterface`
-        and :class:`Symfony\\Component\\Messenger\\Bridge\\AmazonSqs\\MessageGroupAwareInterface`
-        were introduced in Symfony 6.4.
-
     FIFO queues don't support setting a delay per message, a value of ``delay: 0``
     is required in the retry strategy settings.
 
diff --git a/reference/dic_tags.rst b/reference/dic_tags.rst
index 8ffc5eb1b18..94f18efc990 100644
--- a/reference/dic_tags.rst
+++ b/reference/dic_tags.rst
@@ -512,12 +512,6 @@ If you don't need to preload anything, return an empty array. If read-only
 artefacts need to be created, you can store them in a different directory
 with the ``$buildDir`` parameter of the ``warmUp()`` method.
 
-.. versionadded:: 6.4
-
-    The ``$buildDir`` parameter of the
-    :method:`Symfony\\Component\\HttpKernel\\CacheWarmer\\WarmableInterface::warmUp`
-    method was introduced in Symfony 6.4.
-
 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

From bba62162998fb7ef03a37e22b47f2f229fe880ff Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Tue, 24 Oct 2023 10:31:55 +0200
Subject: [PATCH 039/747] Remove obsolete versionadded directives

---
 frontend/asset_mapper.rst          |  6 ------
 reference/configuration/kernel.rst | 16 ----------------
 2 files changed, 22 deletions(-)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index 140c4d22c88..150c57ff05f 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -961,12 +961,6 @@ the polyfill loading.
 
         $ php bin/console importmap:require es-module-shims
 
-.. versionadded:: 6.4
-
-    Passing an importmap name in ``importmap_polyfill`` was
-    introduced in Symfony 6.4. Prior to this, you could pass ``false``
-    or a custom URL to load the polyfill.
-
 ``framework.asset_mapper.importmap_script_attributes``
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/reference/configuration/kernel.rst b/reference/configuration/kernel.rst
index cbfb48f1316..813cd41223c 100644
--- a/reference/configuration/kernel.rst
+++ b/reference/configuration/kernel.rst
@@ -314,10 +314,6 @@ the application is running in web mode and ``web=1&worker=1`` when running in
 a long-running web server. This parameter can be set by using the
 ``APP_RUNTIME_MODE`` env var.
 
-.. versionadded:: 6.4
-
-    The ``kernel.runtime_mode`` parameter was introduced in Symfony 6.4.
-
 ``kernel.runtime_mode.web``
 ---------------------------
 
@@ -325,10 +321,6 @@ a long-running web server. This parameter can be set by using the
 
 Whether the application is running in a web environment.
 
-.. versionadded:: 6.4
-
-    The ``kernel.runtime_mode.web`` parameter was introduced in Symfony 6.4.
-
 ``kernel.runtime_mode.cli``
 ---------------------------
 
@@ -337,10 +329,6 @@ Whether the application is running in a web environment.
 Whether the application is running in a CLI environment. By default,
 this value is the opposite of the ``kernel.runtime_mode.web`` parameter.
 
-.. versionadded:: 6.4
-
-    The ``kernel.runtime_mode.cli`` parameter was introduced in Symfony 6.4.
-
 ``kernel.runtime_mode.worker``
 ------------------------------
 
@@ -349,10 +337,6 @@ this value is the opposite of the ``kernel.runtime_mode.web`` parameter.
 Whether the application is running in a worker/long-running environment. Not all web
 servers support it, and you have to use a long-running web server like `FrankenPHP`_.
 
-.. versionadded:: 6.4
-
-    The ``kernel.runtime_mode.worker`` parameter was introduced in Symfony 6.4.
-
 ``kernel.secret``
 -----------------
 

From 4fd16133498febb9cf9dfb8d2550bcb566f5fc08 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 24 Oct 2023 11:23:29 +0200
Subject: [PATCH 040/747] [PropertyInfo][Serializer] Remove `AnnotationLoader`

---
 _build/redirection_map       |  1 +
 components/property_info.rst | 14 --------------
 components/serializer.rst    | 24 ------------------------
 3 files changed, 1 insertion(+), 38 deletions(-)

diff --git a/_build/redirection_map b/_build/redirection_map
index 90303a53d75..3b845d59ffe 100644
--- a/_build/redirection_map
+++ b/_build/redirection_map
@@ -526,6 +526,7 @@
 /components https://symfony.com/components
 /components/index https://symfony.com/components
 /serializer/normalizers /components/serializer#normalizers
+/components/serializer#component-serializer-attributes-groups-annotations /components/serializer#component-serializer-attributes-groups-attributes
 /logging/monolog_regex_based_excludes /logging/monolog_exclude_http_codes
 /security/named_encoders /security/named_hashers
 /components/inflector /components/string#inflector
diff --git a/components/property_info.rst b/components/property_info.rst
index 0e8a4671d81..452966f57d5 100644
--- a/components/property_info.rst
+++ b/components/property_info.rst
@@ -468,20 +468,6 @@ with the ``property_info`` service in the Symfony Framework::
     // the `serializer_groups` option must be configured (may be set to null)
     $serializerExtractor->getProperties($class, ['serializer_groups' => ['mygroup']]);
 
-.. versionadded:: 6.4
-
-    The
-    :class:`Symfony\\Component\\Serializer\\Mapping\\Loader\\AttributeLoader`
-    was introduced in Symfony 6.4. Prior to this, the
-    :class:`Symfony\\Component\\Serializer\\Mapping\\Loader\\AnnotationLoader`
-    must be used.
-
-.. deprecated:: 6.4
-
-    The
-    :class:`Symfony\\Component\\Serializer\\Mapping\\Loader\\AnnotationLoader`
-    was deprecated in Symfony 6.4.
-
 If ``serializer_groups`` is set to ``null``, serializer groups metadata won't be
 checked but you will get only the properties considered by the Serializer
 Component (notably the ``#[Ignore]`` attribute is taken into account).
diff --git a/components/serializer.rst b/components/serializer.rst
index 9282cfec115..ba2c4a45a4d 100644
--- a/components/serializer.rst
+++ b/components/serializer.rst
@@ -271,14 +271,6 @@ that will be used by the normalizer must be aware of the format to use.
 The following code shows how to initialize the :class:`Symfony\\Component\\Serializer\\Mapping\\Factory\\ClassMetadataFactory`
 for each format:
 
-* Annotations in PHP files::
-
-    use Doctrine\Common\Annotations\AnnotationReader;
-    use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
-    use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
-
-    $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
-
 * Attributes in PHP files::
 
     use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
@@ -300,22 +292,6 @@ for each format:
 
     $classMetadataFactory = new ClassMetadataFactory(new XmlFileLoader('/path/to/your/definition.xml'));
 
-.. versionadded:: 6.4
-
-    The
-    :class:`Symfony\\Component\\Serializer\\Mapping\\Loader\\AttributeLoader`
-    was introduced in Symfony 6.4. Prior to this, the
-    :class:`Symfony\\Component\\Serializer\\Mapping\\Loader\\AnnotationLoader`
-    must be used.
-
-.. deprecated:: 6.4
-
-    Reading annotations in PHP files is deprecated since Symfony 6.4.
-    Also, the
-    :class:`Symfony\\Component\\Serializer\\Mapping\\Loader\\AnnotationLoader`
-    was deprecated in Symfony 6.4.
-
-.. _component-serializer-attributes-groups-annotations:
 .. _component-serializer-attributes-groups-attributes:
 
 Then, create your groups definition:

From 8510eb4be782212c1be9652f7b1c2c0a21aa3e9f Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Sat, 28 Oct 2023 12:38:55 +0200
Subject: [PATCH 041/747] remove versionadded directive for Symfony 6.4

---
 components/phpunit_bridge.rst | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/components/phpunit_bridge.rst b/components/phpunit_bridge.rst
index 44e7d40bb69..f1c81a5769e 100644
--- a/components/phpunit_bridge.rst
+++ b/components/phpunit_bridge.rst
@@ -428,11 +428,6 @@ configuration file:
         </php>
     </phpunit>
 
-.. versionadded:: 6.4
-
-    The support for the ``SYMFONY_PHPUNIT_LOCALE`` environment variable was
-    introduced in Symfony 6.4.
-
 .. _write-assertions-about-deprecations:
 
 Write Assertions about Deprecations

From 2a70cd2819f8a089702cd74b017635fee5de6932 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Mon, 30 Oct 2023 10:58:07 +0100
Subject: [PATCH 042/747] -

---
 security/impersonating_user.rst | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/security/impersonating_user.rst b/security/impersonating_user.rst
index 6b1a57b2eca..22c6ba11c73 100644
--- a/security/impersonating_user.rst
+++ b/security/impersonating_user.rst
@@ -74,10 +74,6 @@ as the value to the current URL:
 
     You can leverage the Twig function ``impersonation_path('thomas')``
 
-    .. versionadded:: 6.4
-
-        The ``impersonation_path()`` function was introduced in Symfony 6.4.
-
 .. tip::
 
     Instead of adding a ``_switch_user`` query string parameter, you can pass

From 7349989b9bb413653def0fda189e057845fdc081 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Sun, 19 Nov 2023 15:01:25 +0100
Subject: [PATCH 043/747] [String] New locale aware casing methods

---
 components/string.rst | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/components/string.rst b/components/string.rst
index f743849fd19..ba73e7387b6 100644
--- a/components/string.rst
+++ b/components/string.rst
@@ -203,7 +203,10 @@ Methods to Change Case
 ::
 
     // changes all graphemes/code points to lower case
-    u('FOO Bar')->lower();  // 'foo bar'
+    u('FOO Bar Brİan')->lower();  // 'foo bar bri̇an'
+    // changes all graphemes/code points to lower case according to locale-specific case mappings
+    u('FOO Bar Brİan')->localeLower('en');  // 'foo bar bri̇an'
+    u('FOO Bar Brİan')->localeLower('lt');  // 'foo bar bri̇̇an'
 
     // when dealing with different languages, uppercase/lowercase is not enough
     // there are three cases (lower, upper, title), some characters have no case,
@@ -213,11 +216,17 @@ Methods to Change Case
     u('Die O\'Brian Straße')->folded(); // "die o'brian strasse"
 
     // changes all graphemes/code points to upper case
-    u('foo BAR')->upper(); // 'FOO BAR'
+    u('foo BAR bάz')->upper(); // 'FOO BAR BΆZ'
+    // changes all graphemes/code points to upper case according to locale-specific case mappings
+    u('foo BAR bάz')->localeUpper('en'); // 'FOO BAR BΆZ'
+    u('foo BAR bάz')->localeUpper('el'); // 'FOO BAR BAZ'
 
     // changes all graphemes/code points to "title case"
-    u('foo bar')->title();     // 'Foo bar'
-    u('foo bar')->title(true); // 'Foo Bar'
+    u('foo ijssel ')->title();     // 'Foo ijssel'
+    u('foo ijssel')->title(true); // 'Foo Ijssel'
+    // changes all graphemes/code points to "title case" according to locale-specific case mappings
+    u('foo ijssel')->localeTitle('en');     // 'Foo ijssel'
+    u('foo ijssel')->localeTitle('nl');     // 'Foo IJssel'
 
     // changes all graphemes/code points to camelCase
     u('Foo: Bar-baz.')->camel(); // 'fooBarBaz'
@@ -226,6 +235,10 @@ Methods to Change Case
     // other cases can be achieved by chaining methods. E.g. PascalCase:
     u('Foo: Bar-baz.')->camel()->title(); // 'FooBarBaz'
 
+.. versionadded:: 7.1
+    The ``localeLower()``, ``localeUpper()`` and ``localeTitle()`` methods were
+    introduced in Symfony 7.1.
+
 The methods of all string classes are case-sensitive by default. You can perform
 case-insensitive operations with the ``ignoreCase()`` method::
 

From 32807059cf0c0f42925eaf7af64320f7338d48e2 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 20 Nov 2023 09:12:08 +0100
Subject: [PATCH 044/747] [Form] Deprecate using `UrlType` without setting
 `default_protocol`

---
 reference/forms/types/url.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/reference/forms/types/url.rst b/reference/forms/types/url.rst
index 5f97fcb89a4..96984b23226 100644
--- a/reference/forms/types/url.rst
+++ b/reference/forms/types/url.rst
@@ -31,6 +31,11 @@ If a value is submitted that doesn't begin with some protocol (e.g. ``http://``,
 ``ftp://``, etc), this protocol will be prepended to the string when
 the data is submitted to the form.
 
+.. deprecated:: 7.1
+
+    Not setting the ``default_protocol`` option is deprecated since Symfony 7.1
+    and will default to ``null`` in Symfony 8.0.
+
 Overridden Options
 ------------------
 

From 64ad9e659ac34d56611f8aaa6ef161ebb8bf5fc0 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 20 Nov 2023 10:25:52 +0100
Subject: [PATCH 045/747] [DependencyInjection] Prepend extension config with
 ContainerConfigurator

---
 bundles/prepend_extension.rst | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/bundles/prepend_extension.rst b/bundles/prepend_extension.rst
index bed3d06da43..4bd1c7c6a67 100644
--- a/bundles/prepend_extension.rst
+++ b/bundles/prepend_extension.rst
@@ -186,6 +186,34 @@ method::
 
     The ``prependExtension()`` method, like ``prepend()``, is called only at compile time.
 
+Alternatively, you can use the ``prepend`` parameter of the
+:method:`Symfony\\Component\\DependencyInjection\\Loader\\ContainerConfigurator::extension`
+method::
+
+    use Symfony\Component\DependencyInjection\ContainerBuilder;
+    use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
+    use Symfony\Component\HttpKernel\Bundle\AbstractBundle;
+
+    class FooBundle extends AbstractBundle
+    {
+        public function prependExtension(ContainerConfigurator $containerConfigurator, ContainerBuilder $containerBuilder): void
+        {
+            // ...
+
+            $containerConfigurator->extension('framework', [
+                'cache' => ['prefix_seed' => 'foo/bar'],
+            ], prepend: true);
+
+            // ...
+        }
+    }
+
+.. versionadded:: 7.1
+
+    The ``prepend`` parameter of the
+    :method:`Symfony\\Component\\DependencyInjection\\Loader\\ContainerConfigurator::extension`
+    method was added in Symfony 7.1.
+
 More than one Bundle using PrependExtensionInterface
 ----------------------------------------------------
 

From 0091e415339f4ffa6d3300cde661cd58f0a92e8d Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 20 Nov 2023 16:28:23 +0100
Subject: [PATCH 046/747] Clean deprecated directives

---
 components/http_foundation.rst | 5 -----
 components/var_exporter.rst    | 6 ------
 2 files changed, 11 deletions(-)

diff --git a/components/http_foundation.rst b/components/http_foundation.rst
index 47be5693bb0..52b999f0f2c 100644
--- a/components/http_foundation.rst
+++ b/components/http_foundation.rst
@@ -518,11 +518,6 @@ It is possible to define partitioned cookies, also known as `CHIPS`_, by using t
     // you can also set the partitioned argument to true when using the `create()` factory method
     $cookie = Cookie::create('name', 'value', partitioned: true);
 
-.. versionadded:: 6.4
-
-    The :method:`Symfony\\Component\\HttpFoundation\\Cookie::withPartitioned`
-    method was introduced in Symfony 6.4.
-
 Managing the HTTP Cache
 ~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/components/var_exporter.rst b/components/var_exporter.rst
index 2b01b7a3f2a..634e4be78cb 100644
--- a/components/var_exporter.rst
+++ b/components/var_exporter.rst
@@ -224,12 +224,6 @@ initialized::
         }
     }
 
-.. deprecated:: 6.4
-
-    Using an array of closures for property-based initialization in the
-    ``createLazyGhost()`` method is deprecated since Symfony 6.4. Pass
-    a single closure that initializes the whole object instead.
-
 :class:`Symfony\\Component\\VarExporter\\LazyGhostTrait` also allows to
 convert non-lazy classes to lazy ones::
 

From 4eb2f258b6552f28e69691c34ab60978c82ab60c Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Sun, 19 Nov 2023 15:40:05 +0100
Subject: [PATCH 047/747] [DependencyInjection] Add urlencode function to
 EnvVarProcessor

---
 configuration/env_var_processors.rst | 50 ++++++++++++++++++++++++++++
 doctrine.rst                         |  9 ++---
 2 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/configuration/env_var_processors.rst b/configuration/env_var_processors.rst
index eba9f4a482c..fc512c84e8e 100644
--- a/configuration/env_var_processors.rst
+++ b/configuration/env_var_processors.rst
@@ -812,6 +812,56 @@ Symfony provides the following env var processors:
             // config/services.php
             $container->setParameter('typed_env', '%env(defined:FOO)%');
 
+.. _urlencode_environment_variable_processor:
+
+``env(urlencode:FOO)``
+    Urlencode the content of ``FOO`` env var. This is especially useful when
+    ``FOO`` value is not compatible with DSN syntax.
+
+    .. configuration-block::
+
+        .. code-block:: yaml
+
+            # config/packages/framework.yaml
+            parameters:
+                env(DATABASE_URL): 'mysql://db_user:foo@b$r@127.0.0.1:3306/db_name'
+                encoded_database_url: '%env(urlencode:DATABASE_URL)%'
+
+        .. code-block:: xml
+
+            <!-- config/packages/framework.xml -->
+            <?xml version="1.0" encoding="UTF-8" ?>
+            <container xmlns="http://symfony.com/schema/dic/services"
+                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                xmlns:framework="http://symfony.com/schema/dic/symfony"
+                xsi:schemaLocation="http://symfony.com/schema/dic/services
+                    https://symfony.com/schema/dic/services/services-1.0.xsd
+                    http://symfony.com/schema/dic/symfony
+                    https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+                <parameters>
+                    <parameter key="env(DATABASE_URL)">mysql://db_user:foo@b$r@127.0.0.1:3306/db_name</parameter>
+                    <parameter key="encoded_database_url">%env(urlencode:DATABASE_URL)%</parameter>
+                </parameters>
+            </container>
+
+        .. code-block:: php
+
+            // config/packages/framework.php
+            namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+            use Symfony\Component\DependencyInjection\ContainerBuilder;
+            use Symfony\Config\FrameworkConfig;
+
+            return static function (ContainerBuilder $container): void {
+                $container->setParameter('env(DATABASE_URL)', 'mysql://db_user:foo@b$r@127.0.0.1:3306/db_name');
+                $container->setParameter('encoded_database_url', '%env(urlencode:DATABASE_URL)%');
+            };
+
+    .. versionadded:: 7.1
+
+        The ``env(urlencode:...)`` env var processor was introduced in Symfony 7.1.
+
 It is also possible to combine any number of processors:
 
 .. configuration-block::
diff --git a/doctrine.rst b/doctrine.rst
index f17307108c1..b024c4e7a4c 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -59,10 +59,11 @@ The database connection information is stored as an environment variable called
 
     If the username, password, host or database name contain any character considered
     special in a URI (such as ``+``, ``@``, ``$``, ``#``, ``/``, ``:``, ``*``, ``!``, ``%``),
-    you must encode them. See `RFC 3986`_ for the full list of reserved characters or
-    use the :phpfunction:`urlencode` function to encode them. In this case you need to
-    remove the ``resolve:`` prefix in ``config/packages/doctrine.yaml`` to avoid errors:
-    ``url: '%env(DATABASE_URL)%'``
+    you must encode them. See `RFC 3986`_ for the full list of reserved characters.
+    You can use the :phpfunction:`urlencode` function to encode them or
+    the :ref:`urlencode environment variable processor <urlencode_environment_variable_processor>`.
+    In this case you need to remove the ``resolve:`` prefix in ``config/packages/doctrine.yaml``
+    to avoid errors: ``url: '%env(DATABASE_URL)%'``
 
 Now that your connection parameters are setup, Doctrine can create the ``db_name``
 database for you:

From 296ee9de94f2652b2ffed15b459d5dc2f13438b5 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 21 Nov 2023 14:39:56 +0100
Subject: [PATCH 048/747] Tweaks

---
 components/string.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/components/string.rst b/components/string.rst
index ba73e7387b6..36df10f4597 100644
--- a/components/string.rst
+++ b/components/string.rst
@@ -222,11 +222,11 @@ Methods to Change Case
     u('foo BAR bάz')->localeUpper('el'); // 'FOO BAR BAZ'
 
     // changes all graphemes/code points to "title case"
-    u('foo ijssel ')->title();     // 'Foo ijssel'
+    u('foo ijssel')->title();     // 'Foo ijssel'
     u('foo ijssel')->title(true); // 'Foo Ijssel'
     // changes all graphemes/code points to "title case" according to locale-specific case mappings
-    u('foo ijssel')->localeTitle('en');     // 'Foo ijssel'
-    u('foo ijssel')->localeTitle('nl');     // 'Foo IJssel'
+    u('foo ijssel')->localeTitle('en'); // 'Foo ijssel'
+    u('foo ijssel')->localeTitle('nl'); // 'Foo IJssel'
 
     // changes all graphemes/code points to camelCase
     u('Foo: Bar-baz.')->camel(); // 'fooBarBaz'

From bd32bca3dd78231b066d59e6af4aeba0e910492e Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 21 Nov 2023 14:47:57 +0100
Subject: [PATCH 049/747] Mention the PHP urlencode() function

---
 configuration/env_var_processors.rst | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/configuration/env_var_processors.rst b/configuration/env_var_processors.rst
index fc512c84e8e..6953781e187 100644
--- a/configuration/env_var_processors.rst
+++ b/configuration/env_var_processors.rst
@@ -815,8 +815,9 @@ Symfony provides the following env var processors:
 .. _urlencode_environment_variable_processor:
 
 ``env(urlencode:FOO)``
-    Urlencode the content of ``FOO`` env var. This is especially useful when
-    ``FOO`` value is not compatible with DSN syntax.
+    Encodes the content of the ``FOO`` env var using the :phpfunction:`urlencode`
+    PHP function. This is especially useful when ``FOO`` value is not compatible
+    with DSN syntax.
 
     .. configuration-block::
 

From c3a8aac346ea87df859a3df276872ba58d3231ae Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Tue, 21 Nov 2023 17:16:37 +0100
Subject: [PATCH 050/747] remove versionadded directive for 6.3

---
 components/serializer.rst | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/components/serializer.rst b/components/serializer.rst
index 0a36d79be20..67aedbef466 100644
--- a/components/serializer.rst
+++ b/components/serializer.rst
@@ -1275,11 +1275,6 @@ to ``true``::
     $result = $normalizer->denormalize($data, Dummy::class, 'json', [AbstractNormalizer::REQUIRE_ALL_PROPERTIES => true]);
     // throws Symfony\Component\Serializer\Exception\MissingConstructorArgumentException
 
-.. versionadded:: 6.3
-
-    The ``AbstractNormalizer::PREVENT_NULLABLE_FALLBACK`` context option
-    was introduced in Symfony 6.3.
-
 Skipping Uninitialized Properties
 ---------------------------------
 

From 5e32c4bb2466c73d6b644bcd5647c3d42e953b17 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Wed, 22 Nov 2023 09:51:22 +0100
Subject: [PATCH 051/747] fix versionadded syntax

---
 components/string.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/components/string.rst b/components/string.rst
index 36df10f4597..323750921a8 100644
--- a/components/string.rst
+++ b/components/string.rst
@@ -236,6 +236,7 @@ Methods to Change Case
     u('Foo: Bar-baz.')->camel()->title(); // 'FooBarBaz'
 
 .. versionadded:: 7.1
+
     The ``localeLower()``, ``localeUpper()`` and ``localeTitle()`` methods were
     introduced in Symfony 7.1.
 

From 7cc8290969d30fd708807b8851558bfefbf173e5 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Thu, 23 Nov 2023 09:08:07 +0100
Subject: [PATCH 052/747] [HttpKernel] Introduce
 `ExceptionEvent::isKernelTerminating()`

---
 components/http_kernel.rst | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/components/http_kernel.rst b/components/http_kernel.rst
index 435ded9063a..fbc59a85a50 100644
--- a/components/http_kernel.rst
+++ b/components/http_kernel.rst
@@ -519,6 +519,17 @@ comes with an :class:`Symfony\\Component\\HttpKernel\\EventListener\\ErrorListen
 which if you choose to use, will do this and more by default (see the sidebar
 below for more details).
 
+The :class:`Symfony\\Component\\HttpKernel\\Event\\ExceptionEvent` exposes the
+:method:`Symfony\\Component\\HttpKernel\\Event\\ExceptionEvent::isKernelTerminating`
+method, which you can use to determine if the kernel is currently terminating
+at the moment the exception was thrown.
+
+.. versionadded:: 7.1
+
+    The
+    :method:`Symfony\\Component\\HttpKernel\\Event\\ExceptionEvent::isKernelTerminating`
+    method was introduced in Symfony 7.1.
+
 .. note::
 
     When setting a response for the ``kernel.exception`` event, the propagation

From 412763397e1705707acb8cdb51a51e14f2ed2ba7 Mon Sep 17 00:00:00 2001
From: "Alexander M. Turek" <me@derrabus.de>
Date: Sat, 25 Nov 2023 17:16:27 +0100
Subject: [PATCH 053/747] Document requirements for DoctrineDbalAdapter

---
 .../cache/adapters/doctrine_dbal_adapter.rst  | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/components/cache/adapters/doctrine_dbal_adapter.rst b/components/cache/adapters/doctrine_dbal_adapter.rst
index fc04410bffc..97b67724ce1 100644
--- a/components/cache/adapters/doctrine_dbal_adapter.rst
+++ b/components/cache/adapters/doctrine_dbal_adapter.rst
@@ -39,5 +39,22 @@ optional arguments::
     necessary to detect the database engine and version without opening the
     connection.
 
+The adapter uses SQL syntax that is optimized for database server that it is connected to.
+The following database servers are known to be compatible:
+
+* MySQL 5.7 and newer
+* MariaDB 10.2 and newer
+* Oracle 10g and newer
+* SQL Server 2012 and newer
+* SQLite 3.24 or later
+* PostgreSQL 9.5 or later
+
+.. note::
+
+    Newer releases of Doctrine DBAL might increase these minimal versions. Please check
+    the manual page on `Doctrine DBAL Platforms`_ if your database server is compatible
+    with the installed Doctrine DBAL version.
+
 .. _`Doctrine DBAL Connection`: https://github.com/doctrine/dbal/blob/master/src/Connection.php
-.. _`Doctrine DBAL URL`: https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
+.. _`Doctrine DBAL URL`: https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/configuration.html#connecting-using-a-url
+.. _`Doctrine DBAL Platforms`: https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/platforms.html
\ No newline at end of file

From 875f4076713ad355283d76f4671dc26defc5192e Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Wed, 29 Nov 2023 10:43:22 +0100
Subject: [PATCH 054/747] remove versionadded directives for Symfony 6

---
 frontend/asset_mapper.rst | 4 ----
 messenger.rst             | 5 -----
 2 files changed, 9 deletions(-)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index 765668ed8ab..c0c8e11040e 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -951,10 +951,6 @@ is useful if you want to avoid leaking sensitive files like ``.env`` or
 
 This option is enabled by default.
 
-.. versionadded:: 6.4
-
-    The ``exclude_dotfiles`` option was introduced in Symfony 6.4.
-
 .. _config-importmap-polyfill:
 
 ``framework.asset_mapper.importmap_polyfill``
diff --git a/messenger.rst b/messenger.rst
index d2f64e74230..8fc7e158cfe 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1586,11 +1586,6 @@ sentinel_master          String, if null or empty Sentinel      null
                          support is disabled
 =======================  =====================================  =================================
 
-.. versionadded:: 6.1
-
-    The ``persistent_id``, ``retry_interval``, ``read_timeout``, ``timeout``, and
-    ``sentinel_master`` options were introduced in Symfony 6.1.
-
 .. caution::
 
     There should never be more than one ``messenger:consume`` command running with the same

From 1f64e6e878a19d719e636f003c76336b49295720 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 1 Dec 2023 16:10:52 +0100
Subject: [PATCH 055/747] Minor tweak

---
 components/cache/adapters/doctrine_dbal_adapter.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/components/cache/adapters/doctrine_dbal_adapter.rst b/components/cache/adapters/doctrine_dbal_adapter.rst
index 97b67724ce1..68732ddd3fa 100644
--- a/components/cache/adapters/doctrine_dbal_adapter.rst
+++ b/components/cache/adapters/doctrine_dbal_adapter.rst
@@ -51,10 +51,10 @@ The following database servers are known to be compatible:
 
 .. note::
 
-    Newer releases of Doctrine DBAL might increase these minimal versions. Please check
-    the manual page on `Doctrine DBAL Platforms`_ if your database server is compatible
-    with the installed Doctrine DBAL version.
+    Newer releases of Doctrine DBAL might increase these minimal versions. Check
+    the manual page on `Doctrine DBAL Platforms`_ if your database server is
+    compatible with the installed Doctrine DBAL version.
 
 .. _`Doctrine DBAL Connection`: https://github.com/doctrine/dbal/blob/master/src/Connection.php
 .. _`Doctrine DBAL URL`: https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/configuration.html#connecting-using-a-url
-.. _`Doctrine DBAL Platforms`: https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/platforms.html
\ No newline at end of file
+.. _`Doctrine DBAL Platforms`: https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/platforms.html

From 7d0f640b523959f2ad6fc6938a36146867146c73 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 1 Dec 2023 16:29:41 +0100
Subject: [PATCH 056/747] Update the Uid version config

---
 components/uid.rst | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/components/uid.rst b/components/uid.rst
index 8b1c496bdc3..26fd32989a9 100644
--- a/components/uid.rst
+++ b/components/uid.rst
@@ -90,10 +90,10 @@ configure the behavior of the factory using configuration files::
         # config/packages/uid.yaml
         framework:
             uid:
-                default_uuid_version: 6
+                default_uuid_version: 7
                 name_based_uuid_version: 5
                 name_based_uuid_namespace: 6ba7b810-9dad-11d1-80b4-00c04fd430c8
-                time_based_uuid_version: 6
+                time_based_uuid_version: 7
                 time_based_uuid_node: 121212121212
 
     .. code-block:: xml
@@ -109,10 +109,10 @@ configure the behavior of the factory using configuration files::
 
             <framework:config>
                 <framework:uid
-                    default_uuid_version="6"
+                    default_uuid_version="7"
                     name_based_uuid_version="5"
                     name_based_uuid_namespace="6ba7b810-9dad-11d1-80b4-00c04fd430c8"
-                    time_based_uuid_version="6"
+                    time_based_uuid_version="7"
                     time_based_uuid_node="121212121212"
                 />
             </framework:config>
@@ -131,10 +131,10 @@ configure the behavior of the factory using configuration files::
 
             $container->extension('framework', [
                 'uid' => [
-                    'default_uuid_version' => 6,
+                    'default_uuid_version' => 7,
                     'name_based_uuid_version' => 5,
                     'name_based_uuid_namespace' => '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
-                    'time_based_uuid_version' => 6,
+                    'time_based_uuid_version' => 7,
                     'time_based_uuid_node' => 121212121212,
                 ],
             ]);
@@ -156,7 +156,7 @@ on the configuration you defined::
 
         public function generate(): void
         {
-            // This creates a UUID of the version given in the configuration file (v6 by default)
+            // This creates a UUID of the version given in the configuration file (v7 by default)
             $uuid = $this->uuidFactory->create();
 
             $nameBasedUuid = $this->uuidFactory->nameBased(/** ... */);

From 03b72037ad4d8794bdf232340a702bfc6e5962f7 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 4 Dec 2023 08:56:36 +0100
Subject: [PATCH 057/747] [PropertyInfo] Introduce
 `PropertyDocBlockExtractorInterface`

---
 components/property_info.rst | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/components/property_info.rst b/components/property_info.rst
index 452966f57d5..ca05d944429 100644
--- a/components/property_info.rst
+++ b/components/property_info.rst
@@ -183,6 +183,26 @@ for a property::
 
 See :ref:`components-property-info-type` for info about the ``Type`` class.
 
+Documentation Block
+~~~~~~~~~~~~~~~~~~~
+
+Extractors that implement :class:`Symfony\\Component\\PropertyInfo\\PropertyDocBlockExtractorInterface`
+can provide the full documentation block for a property as a string::
+
+    $docBlock = $propertyInfo->getDocBlock($class, $property);
+    /*
+        Example Result
+        --------------
+        string(79):
+            This is the subsequent paragraph in the DocComment.
+            It can span multiple lines.
+    */
+
+.. versionadded:: 7.1
+
+    The :class:`Symfony\\Component\\PropertyInfo\\PropertyDocBlockExtractorInterface``
+    interface was introduced in Symfony 7.1.
+
 .. _property-info-description:
 
 Description Information
@@ -413,6 +433,12 @@ library is present::
     // Description information.
     $phpDocExtractor->getShortDescription($class, $property);
     $phpDocExtractor->getLongDescription($class, $property);
+    $phpDocExtractor->getDocBlock($class, $property);
+
+.. versionadded:: 7.1
+
+    The :method:`Symfony\\Component\\PropertyInfo\\Extractor\\PhpDocExtractor::getDocBlock``
+    method was introduced in Symfony 7.1.
 
 PhpStanExtractor
 ~~~~~~~~~~~~~~~~

From 9cc4a78d32588b009e0b6869376b82418f09180d Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Mon, 4 Dec 2023 09:04:40 +0100
Subject: [PATCH 058/747] remove versionadded directives for Symfony 6

---
 frontend/asset_mapper.rst | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index 730c62b1cbd..64768b8e77b 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -379,10 +379,6 @@ from inside ``app.js``:
 Handling CSS
 ------------
 
-.. versionadded:: 6.4
-
-    The ability to import CSS files was introduced in Symfony 6.4.
-
 CSS can be added to your page by importing it from a JavaScript file. The default
 ``assets/app.js`` already imports ``assets/styles/app.css``:
 
@@ -639,10 +635,6 @@ validate the performance of your site!
 Performance: Understanding Preloading
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.4
-
-    Automatic preloading of JavaScript files was introduced in Symfony 6.4.
-
 One issue that LightHouse may report is:
 
     Avoid Chaining Critical Requests

From 4120857b930db4037473660232d912ca4c3b64da Mon Sep 17 00:00:00 2001
From: Daniel Burger <48986191+danielburger1337@users.noreply.github.com>
Date: Mon, 4 Dec 2023 09:04:13 +0100
Subject: [PATCH 059/747] [HttpFoundation] Add
 `UploadedFile::getClientOriginalPath()` to support directory uploads

---
 controller/upload_file.rst     | 14 ++++++++++++--
 reference/forms/types/file.rst | 10 +++++++---
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/controller/upload_file.rst b/controller/upload_file.rst
index c05e78997ba..f638ed0d517 100644
--- a/controller/upload_file.rst
+++ b/controller/upload_file.rst
@@ -194,13 +194,23 @@ There are some important things to consider in the code of the above controller:
    users. This also applies to the files uploaded by your visitors. The ``UploadedFile``
    class provides methods to get the original file extension
    (:method:`Symfony\\Component\\HttpFoundation\\File\\UploadedFile::getClientOriginalExtension`),
-   the original file size (:method:`Symfony\\Component\\HttpFoundation\\File\\UploadedFile::getSize`)
-   and the original file name (:method:`Symfony\\Component\\HttpFoundation\\File\\UploadedFile::getClientOriginalName`).
+   the original file size (:method:`Symfony\\Component\\HttpFoundation\\File\\UploadedFile::getSize`),
+   the original file name (:method:`Symfony\\Component\\HttpFoundation\\File\\UploadedFile::getClientOriginalName`)
+   and the original file path (:method:`Symfony\\Component\\HttpFoundation\\File\\UploadedFile::getClientOriginalPath`).
    However, they are considered *not safe* because a malicious user could tamper
    that information. That's why it's always better to generate a unique name and
    use the :method:`Symfony\\Component\\HttpFoundation\\File\\UploadedFile::guessExtension`
    method to let Symfony guess the right extension according to the file MIME type;
 
+.. note::
+
+    If a directory was uploaded, ``getClientOriginalPath`` will contain the **webkitRelativePath** as provided by the browser.
+    Otherwise this value will be identical to ``getClientOriginalName``.
+
+.. versionadded:: 7.1
+
+    The ``getClientOriginalPath`` method was introduced in Symfony 7.1.
+
 You can use the following code to link to the PDF brochure of a product:
 
 .. code-block:: html+twig
diff --git a/reference/forms/types/file.rst b/reference/forms/types/file.rst
index 95aab73783a..b4982859b98 100644
--- a/reference/forms/types/file.rst
+++ b/reference/forms/types/file.rst
@@ -55,6 +55,10 @@ You might calculate the filename in one of the following ways::
     // use the original file name
     $file->move($directory, $file->getClientOriginalName());
 
+    // when "webkitdirectory" upload was used
+    // otherwise the value will be the same as getClientOriginalName
+    // $file->move($directory, $file->getClientOriginalPath());
+
     // compute a random name and try to guess the extension (more secure)
     $extension = $file->guessExtension();
     if (!$extension) {
@@ -63,9 +67,9 @@ You might calculate the filename in one of the following ways::
     }
     $file->move($directory, rand(1, 99999).'.'.$extension);
 
-Using the original name via ``getClientOriginalName()`` is not safe as it
-could have been manipulated by the end-user. Moreover, it can contain
-characters that are not allowed in file names. You should sanitize the name
+Using the original name via ``getClientOriginalName()`` or ``getClientOriginalPath``
+is not safe as it could have been manipulated by the end-user. Moreover, it can contain
+characters that are not allowed in file names. You should sanitize the value
 before using it directly.
 
 Read :doc:`/controller/upload_file` for an example of how to manage a file

From 1e14f408ff1e4df1e862acadb50a395a550b7efe Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Mon, 4 Dec 2023 21:59:51 +0100
Subject: [PATCH 060/747] append parentheses to method names

---
 controller/upload_file.rst | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/controller/upload_file.rst b/controller/upload_file.rst
index f638ed0d517..f50432f5ee3 100644
--- a/controller/upload_file.rst
+++ b/controller/upload_file.rst
@@ -204,12 +204,13 @@ There are some important things to consider in the code of the above controller:
 
 .. note::
 
-    If a directory was uploaded, ``getClientOriginalPath`` will contain the **webkitRelativePath** as provided by the browser.
-    Otherwise this value will be identical to ``getClientOriginalName``.
+    If a directory was uploaded, ``getClientOriginalPath()`` will contain
+    the **webkitRelativePath** as provided by the browser. Otherwise this
+    value will be identical to ``getClientOriginalName()``.
 
 .. versionadded:: 7.1
 
-    The ``getClientOriginalPath`` method was introduced in Symfony 7.1.
+    The ``getClientOriginalPath()`` method was introduced in Symfony 7.1.
 
 You can use the following code to link to the PDF brochure of a product:
 

From 07905b59655e2354eb5f145caff4685d328b6008 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Fri, 8 Dec 2023 11:32:08 +0100
Subject: [PATCH 061/747] fix markup

---
 components/property_info.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/components/property_info.rst b/components/property_info.rst
index ca05d944429..892cd5345a3 100644
--- a/components/property_info.rst
+++ b/components/property_info.rst
@@ -200,7 +200,7 @@ can provide the full documentation block for a property as a string::
 
 .. versionadded:: 7.1
 
-    The :class:`Symfony\\Component\\PropertyInfo\\PropertyDocBlockExtractorInterface``
+    The :class:`Symfony\\Component\\PropertyInfo\\PropertyDocBlockExtractorInterface`
     interface was introduced in Symfony 7.1.
 
 .. _property-info-description:
@@ -437,7 +437,7 @@ library is present::
 
 .. versionadded:: 7.1
 
-    The :method:`Symfony\\Component\\PropertyInfo\\Extractor\\PhpDocExtractor::getDocBlock``
+    The :method:`Symfony\\Component\\PropertyInfo\\Extractor\\PhpDocExtractor::getDocBlock`
     method was introduced in Symfony 7.1.
 
 PhpStanExtractor

From 5d0f97dbc6a77485fb935aff780c47f6217fd773 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Sat, 9 Dec 2023 10:58:46 +0100
Subject: [PATCH 062/747] [Cache][Messenger] make both options redis_sentinel
 and sentinel_master available everywhere

---
 components/cache/adapters/redis_adapter.rst | 8 ++++++++
 messenger.rst                               | 7 ++++++-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/components/cache/adapters/redis_adapter.rst b/components/cache/adapters/redis_adapter.rst
index a25b1a510ed..1550d419081 100644
--- a/components/cache/adapters/redis_adapter.rst
+++ b/components/cache/adapters/redis_adapter.rst
@@ -200,6 +200,9 @@ Available Options
 ``redis_sentinel`` (type: ``string``, default: ``null``)
     Specifies the master name connected to the sentinels.
 
+``sentinel_master`` (type: ``string``, default: ``null``)
+    Alias of ``redis_sentinel`` option.
+
 ``dbindex`` (type: ``int``, default: ``0``)
     Specifies the database index to select.
 
@@ -211,6 +214,11 @@ Available Options
 ``ssl`` (type: ``array``, default: ``null``)
     SSL context options. See `php.net/context.ssl`_ for more information.
 
+.. versionadded:: 7.1
+
+    The option `sentinel_master` as an alias for `redis_sentinel` was introduced
+    in Symfony 7.1.
+
 .. note::
 
     When using the `Predis`_ library some additional Predis-specific options are available.
diff --git a/messenger.rst b/messenger.rst
index 14ce030f840..07a734d96c9 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1582,9 +1582,14 @@ read_timeout             Float, value in seconds                ``0``
 timeout                  Connection timeout. Float, value in    ``0``
                          seconds default indicates unlimited
 sentinel_master          String, if null or empty Sentinel      null
-                         support is disabled
+redis_sentinel           support is disabled
 =======================  =====================================  =================================
 
+.. versionadded:: 7.1
+
+    The option `redis_sentinel` as an alias for `sentinel_master` was introduced
+    in Symfony 7.1.
+
 .. caution::
 
     There should never be more than one ``messenger:consume`` command running with the same

From ca09716046bd2bf2ccc74e191395e4b26cabd93a Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Sat, 9 Dec 2023 11:23:04 +0100
Subject: [PATCH 063/747] -

---
 workflow/dumping-workflows.rst | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/workflow/dumping-workflows.rst b/workflow/dumping-workflows.rst
index d31b1eb15a8..8262fefd6c1 100644
--- a/workflow/dumping-workflows.rst
+++ b/workflow/dumping-workflows.rst
@@ -80,10 +80,6 @@ The DOT image will look like this :
 
     The ``label`` metadata is not included in the dumped metadata, because it is used as a place's title.
 
-.. versionadded:: 6.4
-
-    The ``--with-metadata`` option was introduced in Symfony 6.4.
-
 You can use ``metadata`` with the following keys to style the workflow:
 
 * for places:

From 1601f09e61fb7b216eab6f09c43c7bb59841e62b Mon Sep 17 00:00:00 2001
From: Jade Xau <98119101+ChibyJade@users.noreply.github.com>
Date: Sat, 9 Dec 2023 12:21:01 +0100
Subject: [PATCH 064/747] Add getEnabledTransition() method

---
 workflow.rst | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/workflow.rst b/workflow.rst
index de69ef6ae73..eb824cc4531 100644
--- a/workflow.rst
+++ b/workflow.rst
@@ -310,6 +310,15 @@ machine type, use ``camelCased workflow name + StateMachine``::
         }
     }
 
+To get all enabled transitions of a Workflow, you can use
+:method:`Symfony\\Component\\Workflow\\WorkflowInterface::getEnabledTransitions`
+method.
+
+.. versionadded:: 7.1
+
+    The :method:`Symfony\\Component\\Workflow\\WorkflowInterface::getEnabledTransitions` method
+    was introduced in Symfony 7.1.
+
 Workflows can also be injected thanks to their name and the
 :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Target`
 attribute::

From 0dc5f71cc141f83d1e94543c387e07a14fd9f3a1 Mon Sep 17 00:00:00 2001
From: Jade Xau <98119101+ChibyJade@users.noreply.github.com>
Date: Sat, 9 Dec 2023 12:25:04 +0100
Subject: [PATCH 065/747] Apply suggestions from code review

---
 workflow.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/workflow.rst b/workflow.rst
index eb824cc4531..3f627d2170f 100644
--- a/workflow.rst
+++ b/workflow.rst
@@ -310,13 +310,13 @@ machine type, use ``camelCased workflow name + StateMachine``::
         }
     }
 
-To get all enabled transitions of a Workflow, you can use
-:method:`Symfony\\Component\\Workflow\\WorkflowInterface::getEnabledTransitions`
+To get the enabled transition of a Workflow, you can use
+:method:`Symfony\\Component\\Workflow\\WorkflowInterface::getEnabledTransition`
 method.
 
 .. versionadded:: 7.1
 
-    The :method:`Symfony\\Component\\Workflow\\WorkflowInterface::getEnabledTransitions` method
+    The :method:`Symfony\\Component\\Workflow\\WorkflowInterface::getEnabledTransition` method
     was introduced in Symfony 7.1.
 
 Workflows can also be injected thanks to their name and the

From 0fe3b79a33ee91ea4f9470d282ebe2baf03b8899 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Sat, 9 Dec 2023 12:25:45 +0100
Subject: [PATCH 066/747] Update workflow.rst

---
 workflow.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/workflow.rst b/workflow.rst
index 3f627d2170f..99d23cdcfae 100644
--- a/workflow.rst
+++ b/workflow.rst
@@ -316,8 +316,8 @@ method.
 
 .. versionadded:: 7.1
 
-    The :method:`Symfony\\Component\\Workflow\\WorkflowInterface::getEnabledTransition` method
-    was introduced in Symfony 7.1.
+    The :method:`Symfony\\Component\\Workflow\\WorkflowInterface::getEnabledTransition`
+    method was introduced in Symfony 7.1.
 
 Workflows can also be injected thanks to their name and the
 :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Target`

From 0c017fd5111e908ea177fc8625d8bacd9cf5ec35 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Fri, 8 Dec 2023 15:55:19 +0100
Subject: [PATCH 067/747] Add Azure mailer

---
 mailer.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/mailer.rst b/mailer.rst
index 3da6c120cb2..fe55ed2d858 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -103,6 +103,7 @@ via a third-party provider:
 Service               Install with
 ===================== ==============================================
 `Amazon SES`_         ``composer require symfony/amazon-mailer``
+`Azure`_              ``composer require symfony/azure-mailer``
 `Brevo`_              ``composer require symfony/brevo-mailer``
 `Infobip`_            ``composer require symfony/infobip-mailer``
 `Mailchimp Mandrill`_ ``composer require symfony/mailchimp-mailer``
@@ -115,6 +116,10 @@ Service               Install with
 `SendGrid`_           ``composer require symfony/sendgrid-mailer``
 ===================== ==============================================
 
+.. versionadded:: 7.1
+
+    The Azure integration was introduced in Symfony 7.1.
+
 .. note::
 
     As a convenience, Symfony also provides support for Gmail (``composer
@@ -167,6 +172,8 @@ party provider:
 |                        | - HTTP ses+https://ACCESS_KEY:SECRET_KEY@default    |
 |                        | - API ses+api://ACCESS_KEY:SECRET_KEY@default       |
 +------------------------+-----------------------------------------------------+
+| `Azure`_               | - API azure+api://ACS_RESOURCE_NAME:KEY@default     |
++------------------------+-----------------------------------------------------+
 | `Brevo`_               | - SMTP brevo+smtp://USERNAME:PASSWORD@default       |
 |                        | - HTTP n/a                                          |
 |                        | - API brevo+api://KEY@default                       |
@@ -1815,6 +1822,7 @@ the :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\MailerAssertionsTrait`::
    handler.
 
 .. _`Amazon SES`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Amazon/README.md
+.. _`Azure`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Azure/README.md
 .. _`App Password`: https://support.google.com/accounts/answer/185833
 .. _`Brevo`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Brevo/README.md
 .. _`default_socket_timeout`: https://www.php.net/manual/en/filesystem.configuration.php#ini.default-socket-timeout

From 566fdd0d6ea379e84d2b9c5db26a10ffa4716630 Mon Sep 17 00:00:00 2001
From: Yassine Guedidi <yassine@guedidi.com>
Date: Sat, 9 Dec 2023 19:30:11 +0100
Subject: [PATCH 068/747] IsCsrfTokenValid documentation

---
 security/csrf.rst | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/security/csrf.rst b/security/csrf.rst
index be7bb909f61..2e2197f1547 100644
--- a/security/csrf.rst
+++ b/security/csrf.rst
@@ -164,6 +164,26 @@ method to check its validity::
         }
     }
 
+Alternatively you can use the
+:class:`Symfony\\Component\\Security\\Http\\Attribute\\IsCsrfTokenValid`
+attribute on the controller action::
+
+    use Symfony\Component\HttpFoundation\Request;
+    use Symfony\Component\HttpFoundation\Response;
+    use Symfony\Component\Security\Http\Attribute\IsCsrfTokenValid;
+    // ...
+
+    #[IsCsrfTokenValid('delete-item', tokenKey: 'token')]
+    public function delete(Request $request): Response
+    {
+        // ... do something, like deleting an object
+    }
+
+.. versionadded:: 7.1
+
+    The :class:`Symfony\\Component\\Security\\Http\\Attribute\\IsCsrfTokenValid`
+    attribute was introduced in Symfony 7.1.
+
 CSRF Tokens and Compression Side-Channel Attacks
 ------------------------------------------------
 

From 47caec8a448b0ab696d419959bd7ca929ccbe60b Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Sat, 9 Dec 2023 19:37:43 +0100
Subject: [PATCH 069/747] Remove obsolete versionadded directive

---
 security/access_token.rst | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/security/access_token.rst b/security/access_token.rst
index 37942e950c4..29fbfbc8bb6 100644
--- a/security/access_token.rst
+++ b/security/access_token.rst
@@ -700,11 +700,6 @@ create your own User from the claims, you must
 Creating Users from Token
 -------------------------
 
-.. versionadded:: 6.3
-
-    The possibility to omit the user provider in case of stateless firewalls
-    was introduced in Symfony 6.3.
-
 Some types of tokens (for instance OIDC) contain all information required
 to create a user entity (e.g. username and roles). In this case, you don't
 need a user provider to create a user from the database::

From 7b47bdc409d47c082a7a0c7c5d9713ba9606d9b1 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Sat, 9 Dec 2023 19:42:52 +0100
Subject: [PATCH 070/747] Add `#[IsCsrfTokenValid]` to attributes reference

---
 reference/attributes.rst | 1 +
 security/csrf.rst        | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/reference/attributes.rst b/reference/attributes.rst
index cf21c5a7c45..f61c78b9a3a 100644
--- a/reference/attributes.rst
+++ b/reference/attributes.rst
@@ -80,6 +80,7 @@ Security
 ~~~~~~~~
 
 * :ref:`CurrentUser <security-json-login>`
+* :ref:`IsCsrfTokenValid <csrf-controller-attributes>`
 * :ref:`IsGranted <security-securing-controller-attributes>`
 
 Serializer
diff --git a/security/csrf.rst b/security/csrf.rst
index 2e2197f1547..0352d7e6f87 100644
--- a/security/csrf.rst
+++ b/security/csrf.rst
@@ -164,6 +164,8 @@ method to check its validity::
         }
     }
 
+.. _csrf-controller-attributes:
+
 Alternatively you can use the
 :class:`Symfony\\Component\\Security\\Http\\Attribute\\IsCsrfTokenValid`
 attribute on the controller action::

From 2e45f6af526da40d228dafe40bf31e57e262da76 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Sun, 10 Dec 2023 09:54:31 +0100
Subject: [PATCH 071/747] [Form] Add `keep_as_list` option

---
 reference/forms/types/collection.rst | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/reference/forms/types/collection.rst b/reference/forms/types/collection.rst
index d1e1f0fb00b..2d91bfd06bd 100644
--- a/reference/forms/types/collection.rst
+++ b/reference/forms/types/collection.rst
@@ -229,6 +229,27 @@ you'd use the :doc:`EmailType </reference/forms/types/email>`. If you want
 to embed a collection of some other form, pass the form type class as this
 option (e.g. ``MyFormType::class``).
 
+keep_as_list
+~~~~~~~~~~~~
+
+**type**: ``boolean`` **default**: ``false``
+
+When set to ``true``, the ``keep_as_list`` option affects the reindexing
+of nested form names within a collection. This feature is particularly useful
+when working with collection types and removing items from the collection
+during form submission.
+
+When this option is set to ``false``, if you have a collection of 3 items and
+you remove the second item, the indexes will be ``0`` and ``2`` when validating
+the collection. However, by enabling the ``keep_as_list`` option and setting
+it to ``true``, the indexes will be reindexed as ``0`` and ``1``. This ensures
+that the indexes remain consecutive and do not have gaps, providing a clearer
+and more predictable structure for your nested forms.
+
+.. versionadded:: 7.1
+
+    The ``keep_as_list`` option was introduced in Symfony 7.1.
+
 prototype
 ~~~~~~~~~
 

From 2c88dc8c3162ad4e96bf6d309f19ed27eb13689e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Sch=C3=A4dlich?= <schaedlich.jan@gmail.com>
Date: Sat, 25 Nov 2023 10:45:09 +0100
Subject: [PATCH 072/747] Improve `debug:serializer` command documentation by
 adding `serializedPath`

---
 serializer.rst | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/serializer.rst b/serializer.rst
index ef155a1a45d..9731e9b869e 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -511,20 +511,22 @@ given class:
         |          |   "groups" => [                                            |
         |          |       "book:read",                                         |
         |          |       "book:write",                                        |
-        |          |   ]                                                        |
+        |          |   ],                                                       |
         |          |   "maxDepth" => 1,                                         |
-        |          |   "serializedName" => "book_name"                          |
-        |          |   "ignore" => false                                        |
+        |          |   "serializedName" => "book_name",                         |
+        |          |   "serializedPath" => null,                                |
+        |          |   "ignore" => false,                                       |
         |          |   "normalizationContexts" => [],                           |
         |          |   "denormalizationContexts" => []                          |
         |          | ]                                                          |
         | isbn     | [                                                          |
         |          |   "groups" => [                                            |
         |          |       "book:read",                                         |
-        |          |   ]                                                        |
+        |          |   ],                                                       |
         |          |   "maxDepth" => null,                                      |
-        |          |   "serializedName" => null                                 |
-        |          |   "ignore" => false                                        |
+        |          |   "serializedName" => null,                                |
+        |          |   "serializedPath" => [data][isbn],                        |
+        |          |   "ignore" => false,                                       |
         |          |   "normalizationContexts" => [],                           |
         |          |   "denormalizationContexts" => []                          |
         |          | ]                                                          |

From 4336b8735cf2e22004c51302d7b5678afab3e32e Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Tue, 12 Dec 2023 12:15:00 +0100
Subject: [PATCH 073/747] -

---
 reference/configuration/framework.rst | 4 ----
 webhook.rst                           | 4 ----
 2 files changed, 8 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index b5a2c547eb1..894cf7a82c5 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -3550,10 +3550,6 @@ Adds a `Link HTTP header`_ to the response.
 webhook
 ~~~~~~~
 
-.. versionadded:: 6.3
-
-    The Webhook configuration was introduced in Symfony 6.3.
-
 The ``webhook`` option (and its children) are used to configure the webhooks
 defined in your application. Read more about the options in the :ref:`Webhook documentation <webhook>`.
 
diff --git a/webhook.rst b/webhook.rst
index f9bde7451a9..f65760182a8 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -1,10 +1,6 @@
 Webhook
 =======
 
-.. versionadded:: 6.3
-
-    The Webhook component was introduced in Symfony 6.3.
-
 The Webhook component is used to respond to remote webhooks to trigger actions
 in your application. This document focuses on using webhooks to listen to remote
 events in other Symfony components.

From cc8abdd50c873b90d44ff91291c33fc9df0bb152 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Tue, 12 Dec 2023 13:25:01 +0100
Subject: [PATCH 074/747] -

---
 webhook.rst | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/webhook.rst b/webhook.rst
index 4e7377cf730..74e48499937 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -86,15 +86,6 @@ Sendgrid ``mailer.webhook.request_parser.sendgrid``
 Vonage   ``notifier.webhook.request_parser.vonage``
 ======== ==========================================
 
-.. versionadded:: 6.3
-
-    The support for Mailgun and Postmark was introduced in Symfony 6.3.
-
-.. versionadded:: 6.4
-
-    The support for Brevo, Mailjet, Sendgrid and Vonage was introduced in
-    Symfony 6.4.
-
 Set up the webhook in the third-party mailer. For Mailgun, you can do this
 in the control panel. As URL, make sure to use the ``/webhook/mailer_mailgun``
 path behind the domain you're using.

From 8ebe0dd9de58c25e266bfcc943198f5829006d4f Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 12 Dec 2023 14:10:17 +0100
Subject: [PATCH 075/747] [Messenger] Add `--all` option to `messenger:consume`

---
 messenger.rst | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index 133283fe465..adaec5a9883 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -485,6 +485,17 @@ The first argument is the receiver's name (or service id if you routed to a
 custom service). By default, the command will run forever: looking for new messages
 on your transport and handling them. This command is called your "worker".
 
+If you want to consume messages from all available receivers, you can use the
+command with the ``--all`` option:
+
+.. code-block:: terminal
+
+    $ php bin/console messenger:consume --all
+
+.. versionadded:: 7.1
+
+    The ``--all`` option was introduced in Symfony 7.1.
+
 .. tip::
 
     To properly stop a worker, throw an instance of

From 457d5e566b21758cc2b84f987eef3d56388f4ab4 Mon Sep 17 00:00:00 2001
From: Louis-Marie <lm.gabo@gmail.com>
Date: Wed, 13 Dec 2023 08:50:00 +0100
Subject: [PATCH 076/747] Remove @dev

---
 setup.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/setup.rst b/setup.rst
index 49b6f9482de..7da5a5fcb12 100644
--- a/setup.rst
+++ b/setup.rst
@@ -46,10 +46,10 @@ application:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ symfony new my_project_directory --version="7.0.*@dev" --webapp
+    $ symfony new my_project_directory --version="7.0.*" --webapp
 
     # run this if you are building a microservice, console application or API
-    $ symfony new my_project_directory --version="7.0.*@dev"
+    $ symfony new my_project_directory --version="7.0.*"
 
 The only difference between these two commands is the number of packages
 installed by default. The ``--webapp`` option installs all the packages that you
@@ -61,12 +61,12 @@ Symfony application using Composer:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ composer create-project symfony/skeleton:"7.0.*@dev" my_project_directory
+    $ composer create-project symfony/skeleton:"7.0.*" my_project_directory
     $ cd my_project_directory
     $ composer require webapp
 
     # run this if you are building a microservice, console application or API
-    $ composer create-project symfony/skeleton:"7.0.*@dev" my_project_directory
+    $ composer create-project symfony/skeleton:"7.0.*" my_project_directory
 
 No matter which command you run to create the Symfony application. All of them
 will create a new ``my_project_directory/`` directory, download some dependencies

From 46de3924533620cd415c2f5f3d5123b134c96da7 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 13 Dec 2023 08:52:43 +0100
Subject: [PATCH 077/747] [Cache] Deprecate `CouchbaseBucketAdapter`

---
 components/cache/adapters/couchbasebucket_adapter.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/components/cache/adapters/couchbasebucket_adapter.rst b/components/cache/adapters/couchbasebucket_adapter.rst
index c279e1f8780..8927a8c53f8 100644
--- a/components/cache/adapters/couchbasebucket_adapter.rst
+++ b/components/cache/adapters/couchbasebucket_adapter.rst
@@ -1,6 +1,12 @@
 Couchbase Bucket Cache Adapter
 ==============================
 
+.. deprecated:: 7.1
+
+    The ``CouchbaseBucketAdapter`` is deprecated since Symfony 7.1, use the
+    :doc:`CouchbaseCollectionAdapter </components/cache/adapters/couchbasecollection_adapter>`
+    instead.
+
 This adapter stores the values in-memory using one (or more) `Couchbase server`_
 instances. Unlike the :doc:`APCu adapter </components/cache/adapters/apcu_adapter>`, and similarly to the
 :doc:`Memcached adapter </components/cache/adapters/memcached_adapter>`, it is not limited to the current server's

From 62b41a0cd5c01d15731d637a00a1799e61b767b9 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Wed, 13 Dec 2023 09:36:51 +0100
Subject: [PATCH 078/747] remove 6.x versionnaded in webhook

---
 webhook.rst | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/webhook.rst b/webhook.rst
index 889f6bac174..8be38d80408 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -145,14 +145,6 @@ Twilio       ``notifier.webhook.request_parser.twilio``
 Vonage       ``notifier.webhook.request_parser.vonage``
 ============ ==========================================
 
-.. versionadded:: 6.3
-
-    The support for Twilio was introduced in Symfony 6.3.
-
-.. versionadded:: 6.4
-
-    The support for Vonage was introduced in Symfony 6.4.
-
 For SMS transports, an additional ``SmsEvent`` is available in the RemoteEvent
 consumer::
 

From 6de3f76d83cae369726403e8af132cadfa492da3 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Wed, 13 Dec 2023 10:30:46 +0100
Subject: [PATCH 079/747] remove versionadded directive for Symfony 6

---
 security.rst | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/security.rst b/security.rst
index 2c67ec8d073..e275ec4add0 100644
--- a/security.rst
+++ b/security.rst
@@ -1857,11 +1857,6 @@ you have imported the logout route loader in your routes:
             $routes->import('security.route_loader.logout', 'service');
         };
 
-.. versionadded:: 6.4
-
-    The :class:`Symfony\\Bundle\\SecurityBundle\\Routing\\LogoutRouteLoader` was
-    introduced in Symfony 6.4.
-
 Logout programmatically
 ~~~~~~~~~~~~~~~~~~~~~~~
 

From 57f78401f85694b174572dadab73a0ffdab6380b Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Thu, 14 Dec 2023 08:21:40 +0100
Subject: [PATCH 080/747] -

---
 messenger.rst | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index 58573dab7a9..25d6b519960 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -884,10 +884,6 @@ running the ``messenger:consume`` command.
 Rate limited transport
 ~~~~~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 6.2
-
-    The ``rate_limiter`` option was introduced in Symfony 6.2.
-
 Sometimes you might need to rate limit your message worker. You can configure a
 rate limiter on a transport (requires the :doc:`RateLimiter component </rate-limiter>`)
 by setting its ``rate_limiter`` option:

From be9cb027cc149a1ae6f1b8b17339b0d21c02d661 Mon Sep 17 00:00:00 2001
From: Maxime Doutreluingne <maxime.doutreluingne@gmail.com>
Date: Fri, 15 Dec 2023 18:10:04 +0100
Subject: [PATCH 081/747] [Notifier] Add Bluesky notifier bridge

---
 console.rst  | 4 ----
 notifier.rst | 6 ++++++
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/console.rst b/console.rst
index 6a0806c730a..700ed536486 100644
--- a/console.rst
+++ b/console.rst
@@ -611,10 +611,6 @@ profile is accessible through the web page of the profiler.
     terminal supports links). If you run it in debug verbosity (``-vvv``) you'll
     also see the time and memory consumed by the command.
 
-.. versionadded:: 6.4
-
-    The ``--profile`` option was introduced in Symfony 6.4.
-
 Learn More
 ----------
 
diff --git a/notifier.rst b/notifier.rst
index 42f55201073..8cb9b87c0dd 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -221,6 +221,7 @@ integration with these chat services:
 Service                                  Package                               DSN
 =======================================  ====================================  =============================================================================
 `AmazonSns`_                             ``symfony/amazon-sns-notifier``       ``sns://ACCESS_KEY:SECRET_KEY@default?region=REGION``
+`Bluesky`_                               ``symfony/bluesky-notifier``          ``bluesky://USERNAME:PASSWORD@default``
 `Chatwork`_                              ``symfony/chatwork-notifier``         ``chatwork://API_TOKEN@default?room_id=ID``
 `Discord`_                               ``symfony/discord-notifier``          ``discord://TOKEN@default?webhook_id=ID``
 `FakeChat`_                              ``symfony/fake-chat-notifier``        ``fakechat+email://default?to=TO&from=FROM`` or ``fakechat+logger://default``
@@ -241,6 +242,10 @@ Service                                  Package                               D
 `Zulip`_                                 ``symfony/zulip-notifier``            ``zulip://EMAIL:TOKEN@HOST?channel=CHANNEL``
 ======================================   ====================================  =============================================================================
 
+.. versionadded:: 7.1
+
+    The ``Bluesky`` integration was introduced in Symfony 7.1.
+
 Chatters are configured using the ``chatter_transports`` setting:
 
 .. code-block:: bash
@@ -942,6 +947,7 @@ is dispatched. Listeners receive a
 .. _`AllMySms`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/AllMySms/README.md
 .. _`AmazonSns`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/AmazonSns/README.md
 .. _`Bandwidth`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Bandwidth/README.md
+.. _`Bluesky`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Bluesky/README.md
 .. _`Brevo`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Brevo/README.md
 .. _`Chatwork`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Chatwork/README.md
 .. _`Clickatell`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Clickatell/README.md

From dbcfe2f3bd91a421007e44ecc372f7f5294c27fc Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Sat, 16 Dec 2023 09:57:50 +0100
Subject: [PATCH 082/747] -

---
 console.rst | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/console.rst b/console.rst
index 6a0806c730a..700ed536486 100644
--- a/console.rst
+++ b/console.rst
@@ -611,10 +611,6 @@ profile is accessible through the web page of the profiler.
     terminal supports links). If you run it in debug verbosity (``-vvv``) you'll
     also see the time and memory consumed by the command.
 
-.. versionadded:: 6.4
-
-    The ``--profile`` option was introduced in Symfony 6.4.
-
 Learn More
 ----------
 

From 9e47f5fe8489c1b6aadbb241a4fe30faf1aebfea Mon Sep 17 00:00:00 2001
From: Farhad Safarov <farhad.safarov@gmail.com>
Date: Sun, 17 Dec 2023 01:03:31 +0300
Subject: [PATCH 083/747] [Notifier] Add Unifonic notifier bridge

---
 notifier.rst | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/notifier.rst b/notifier.rst
index 8cb9b87c0dd..b57f501687d 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -98,6 +98,7 @@ Service             Package                                DSN
 `Telnyx`_           ``symfony/telnyx-notifier``            ``telnyx://API_KEY@default?from=FROM&messaging_profile_id=MESSAGING_PROFILE_ID``
 `TurboSms`_         ``symfony/turbo-sms-notifier``         ``turbosms://AUTH_TOKEN@default?from=FROM``
 `Twilio`_           ``symfony/twilio-notifier``            ``twilio://SID:TOKEN@default?from=FROM``                                                                                  yes
+`Unifonic`_         ``symfony/unifonic-notifier``          ``unifonic://APP_SID@default?from=FROM``
 `Vonage`_           ``symfony/vonage-notifier``            ``vonage://KEY:SECRET@default?from=FROM``                                                                                 yes
 `Yunpian`_          ``symfony/yunpian-notifier``           ``yunpian://APIKEY@default``
 ==================  =====================================  ========================================================================================================================= ===============
@@ -244,7 +245,7 @@ Service                                  Package                               D
 
 .. versionadded:: 7.1
 
-    The ``Bluesky`` integration was introduced in Symfony 7.1.
+    The ``Bluesky`` and ``Unifonic`` integrations were introduced in Symfony 7.1.
 
 Chatters are configured using the ``chatter_transports`` setting:
 
@@ -1008,6 +1009,7 @@ is dispatched. Listeners receive a
 .. _`TurboSms`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/TurboSms/README.md
 .. _`Twilio`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Twilio/README.md
 .. _`Twitter`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Twitter/README.md
+.. _`Unifonic`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Unifonic/README.md
 .. _`Vonage`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Vonage/README.md
 .. _`Yunpian`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Yunpian/README.md
 .. _`Zendesk`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Zendesk/README.md

From 6bd49488eebe6195e7df021b9057988c539b49cb Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Sun, 17 Dec 2023 20:29:35 +0100
Subject: [PATCH 084/747] [HttpClient] Add `JsonMockResponse::fromFile()` and
 `MockResponse::fromFile()` shortcuts

---
 http_client.rst | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/http_client.rst b/http_client.rst
index 2ca591a5098..6d45fc6d6d7 100644
--- a/http_client.rst
+++ b/http_client.rst
@@ -1905,6 +1905,20 @@ in order when requests are made::
     $response1 = $client->request('...'); // returns $responses[0]
     $response2 = $client->request('...'); // returns $responses[1]
 
+It is also possible to create a
+:class:`Symfony\\Component\\HttpClient\\Response\\MockResponse` directly
+from a file, which is particularly useful when storing your responses
+snapshots in files::
+
+    use Symfony\Component\HttpClient\Response\MockResponse;
+
+    $response = MockResponse::fromFile('tests/fixtures/response.xml');
+
+.. versionadded:: 7.1
+
+    The :method:`Symfony\\Component\\HttpClient\\Response\\MockResponse::fromFile`
+    method was introduced in Symfony 7.1.
+
 Another way of using :class:`Symfony\\Component\\HttpClient\\MockHttpClient` is to
 pass a callback that generates the responses dynamically when it's called::
 
@@ -2079,6 +2093,19 @@ You can use :class:`Symfony\\Component\\HttpClient\\Response\\JsonMockResponse`
         'foo' => 'bar',
     ]);
 
+Just like :class:`Symfony\\Component\\HttpClient\\Response\\MockResponse`, you can
+also create a :class:`Symfony\\Component\\HttpClient\\Response\\JsonMockResponse`
+directly from a file::
+
+    use Symfony\Component\HttpClient\Response\JsonMockResponse;
+
+    $response = JsonMockResponse::fromFile('tests/fixtures/response.json');
+
+.. versionadded:: 7.1
+
+    The :method:`Symfony\\Component\\HttpClient\\Response\\JsonMockResponse::fromFile`
+    method was introduced in Symfony 7.1.
+
 Testing Request Data
 ~~~~~~~~~~~~~~~~~~~~
 

From b89fb23bdd9ed4b8607d69d287cd6136f9d0fbcc Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 19 Dec 2023 20:51:02 +0100
Subject: [PATCH 085/747] [FrameworkBundle][RateLimiter] Add `rate_limiter` tag
 to rate limiter services

---
 rate_limiter.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/rate_limiter.rst b/rate_limiter.rst
index 7453e1e70bc..8c667dd3f59 100644
--- a/rate_limiter.rst
+++ b/rate_limiter.rst
@@ -215,6 +215,16 @@ at a rate of another 500 requests every 15 minutes. If you don't make that
 number of requests, the unused ones don't accumulate (the ``limit`` option
 prevents that number from being higher than 5,000).
 
+.. tip::
+
+    All rate-limiters are tagged with the ``rate_limiter`` tag, so you can
+    easily find them with a tagged iterator or locator.
+
+    .. versionadded:: 7.1
+
+        The automatic addition of the ``rate_limiter`` tag was introduced
+        in Symfony 7.1.
+
 Rate Limiting in Action
 -----------------------
 

From e12c974d310d690472d9b67d062fa316dc2b5983 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 20 Dec 2023 08:49:58 +0100
Subject: [PATCH 086/747] [Validator] Add `list` and `associative_array` types
 to Type constraint

---
 reference/constraints/Type.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/reference/constraints/Type.rst b/reference/constraints/Type.rst
index 1bb4035c7fd..b8f41fbd524 100644
--- a/reference/constraints/Type.rst
+++ b/reference/constraints/Type.rst
@@ -190,6 +190,11 @@ PHP class/interface or a valid PHP datatype (checked by PHP's ``is_()`` function
 * :phpfunction:`resource <is_resource>`
 * :phpfunction:`null <is_null>`
 
+If you're dealing with arrays, you can use the following types in the constraint:
+
+* ``list`` which uses :phpfunction:`array_is_list <array_is_list>` internally
+* ``associative_array`` which is true for any **non-empty** array that is not a list
+
 Also, you can use ``ctype_*()`` functions from corresponding
 `built-in PHP extension`_. Consider `a list of ctype functions`_:
 
@@ -208,6 +213,11 @@ Also, you can use ``ctype_*()`` functions from corresponding
 Make sure that the proper :phpfunction:`locale <setlocale>` is set before
 using one of these.
 
+.. versionadded:: 7.1
+
+    The ``list`` and ``associative_array`` types were introduced in Symfony
+    7.1.
+
 Finally, you can use aggregated functions:
 
 * ``number``: ``is_int || is_float && !is_nan``

From c7ac483dd76079af66756a35eb27ab401b72abd6 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Wed, 20 Dec 2023 09:14:11 +0100
Subject: [PATCH 087/747] fix typo

---
 http_client.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/http_client.rst b/http_client.rst
index 81e3b3068c9..530b2aeaf8f 100644
--- a/http_client.rst
+++ b/http_client.rst
@@ -1907,7 +1907,7 @@ in order when requests are made::
 
 It is also possible to create a
 :class:`Symfony\\Component\\HttpClient\\Response\\MockResponse` directly
-from a file, which is particularly useful when storing your responses
+from a file, which is particularly useful when storing your response
 snapshots in files::
 
     use Symfony\Component\HttpClient\Response\MockResponse;

From 62aeccb52ec4ef5b6ea39aa0632c5c480ffda10d Mon Sep 17 00:00:00 2001
From: Alan ZARLI <azarli@milnr3.com>
Date: Mon, 18 Dec 2023 16:36:01 +0100
Subject: [PATCH 088/747] [Notifier] Add Smsbox notifier bridge

---
 notifier.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/notifier.rst b/notifier.rst
index b57f501687d..a8f658cbe62 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -92,6 +92,7 @@ Service             Package                                DSN
 `Sinch`_            ``symfony/sinch-notifier``             ``sinch://ACCOUNT_ID:AUTH_TOKEN@default?from=FROM``
 `Smsapi`_           ``symfony/smsapi-notifier``            ``smsapi://TOKEN@default?from=FROM``
 `SmsBiuras`_        ``symfony/sms-biuras-notifier``        ``smsbiuras://UID:API_KEY@default?from=FROM&test_mode=0``
+`Smsbox`_           ``symfony/smsbox-notifier``            ``smsbox://APIKEY@default?mode=MODE&strategy=STRATEGY&sender=SENDER``
 `Smsc`_             ``symfony/smsc-notifier``              ``smsc://LOGIN:PASSWORD@default?from=FROM``
 `SMSFactor`_        ``symfony/sms-factor-notifier``        ``sms-factor://TOKEN@default?sender=SENDER&push_type=PUSH_TYPE``
 `SpotHit`_          ``symfony/spot-hit-notifier``          ``spothit://TOKEN@default?from=FROM``
@@ -245,7 +246,7 @@ Service                                  Package                               D
 
 .. versionadded:: 7.1
 
-    The ``Bluesky`` and ``Unifonic`` integrations were introduced in Symfony 7.1.
+    The ``Bluesky``, ``Unifonic`` and ``Smsbox`` integrations were introduced in Symfony 7.1.
 
 Chatters are configured using the ``chatter_transports`` setting:
 

From 6eaf0d28c4a51d322a1f4dac9945cecf1c262d39 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 20 Dec 2023 15:44:04 +0100
Subject: [PATCH 089/747] Minor tweak

---
 rate_limiter.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/rate_limiter.rst b/rate_limiter.rst
index 8c667dd3f59..818660498a8 100644
--- a/rate_limiter.rst
+++ b/rate_limiter.rst
@@ -218,7 +218,8 @@ prevents that number from being higher than 5,000).
 .. tip::
 
     All rate-limiters are tagged with the ``rate_limiter`` tag, so you can
-    easily find them with a tagged iterator or locator.
+    find them with a :doc:`tagged iterator </service_container/tags>` or
+    :doc:`locator </service_container/service_subscribers_locators>`.
 
     .. versionadded:: 7.1
 

From f32a8cf34775c2b509c2312a610213aa5de29291 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Wed, 20 Dec 2023 13:58:44 +0100
Subject: [PATCH 090/747] [Security] Update request matcher doc

---
 security/access_control.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/security/access_control.rst b/security/access_control.rst
index 1da469a1f33..a8a0a3e2987 100644
--- a/security/access_control.rst
+++ b/security/access_control.rst
@@ -19,10 +19,10 @@ things:
 1. Matching Options
 -------------------
 
-Symfony creates an instance of :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher`
-for each ``access_control`` entry, which determines whether or not a given
-access control should be used on this request. The following ``access_control``
-options are used for matching:
+Symfony uses :class:`Symfony\\Component\\HttpFoundation\\ChainRequestMatcher` for
+each ``access_control`` entry, which determines which implementation of
+:class:`Symfony\\Component\\HttpFoundation\\RequestMatcherInterface` should be used
+on this request. The following ``access_control`` options are used for matching:
 
 * ``path``: a regular expression (without delimiters)
 * ``ip`` or ``ips``: netmasks are also supported (can be a comma-separated string)

From 9f4b6263f317b38b9294a6d0622cc79ea6d598ae Mon Sep 17 00:00:00 2001
From: Simon <smn.andre@gmail.com>
Date: Thu, 21 Dec 2023 09:54:44 +0100
Subject: [PATCH 091/747] [String] Remove confusing paragraph about
 `withEmoji('strip')`

---
 components/intl.rst   |  9 +++++++++
 components/string.rst | 10 ----------
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/components/intl.rst b/components/intl.rst
index 46146e47e1b..8dde23105a6 100644
--- a/components/intl.rst
+++ b/components/intl.rst
@@ -424,6 +424,15 @@ platforms::
     $transliterator->transliterate('Menus with 🥗 or 🧆');
     // => 'Menus with :green_salad: or :falafel:'
 
+Furthermore the ``EmojiTransliterator`` provides a special ``strip`` locale
+that removes all the emojis from a string::
+
+    use Symfony\Component\Intl\Transliterator\EmojiTransliterator;
+
+    $transliterator = EmojiTransliterator::create('strip');
+    $transliterator->transliterate('🎉Hey!🥳 🎁Happy Birthday!🎁');
+    // => 'Hey! Happy Birthday!'
+
 .. tip::
 
     Combine this emoji transliterator with the :ref:`Symfony String slugger <string-slugger-emoji>`
diff --git a/components/string.rst b/components/string.rst
index f743849fd19..b3d9bb7954b 100644
--- a/components/string.rst
+++ b/components/string.rst
@@ -589,16 +589,6 @@ from GitHub or Slack, use the first argument of ``withEmoji()`` method::
     $slug = $slugger->slug('a 😺, 🐈‍⬛, and a 🦁');
     // $slug = 'a-smiley-cat-black-cat-and-a-lion';
 
-If you want to strip emojis from slugs, use the special ``strip`` locale::
-
-    use Symfony\Component\String\Slugger\AsciiSlugger;
-
-    $slugger = new AsciiSlugger();
-    $slugger = $slugger->withEmoji('strip');
-
-    $slug = $slugger->slug('a 😺, 🐈‍⬛, and a 🦁');
-    // $slug = 'a-and-a';
-
 .. _string-inflector:
 
 Inflector

From 8d69319ff59ef8ae2498469e405289c5bbdb604c Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Sat, 23 Dec 2023 18:37:12 +0100
Subject: [PATCH 092/747] Remove reference to some removed classes

---
 create_framework/http_kernel_httpkernel_class.rst |  5 -----
 introduction/from_flat_php_to_symfony.rst         | 11 +++++------
 messenger.rst                                     |  2 +-
 3 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/create_framework/http_kernel_httpkernel_class.rst b/create_framework/http_kernel_httpkernel_class.rst
index fa673f9ba57..ecf9d4c7879 100644
--- a/create_framework/http_kernel_httpkernel_class.rst
+++ b/create_framework/http_kernel_httpkernel_class.rst
@@ -114,11 +114,6 @@ client; that's what the ``ResponseListener`` does::
 
     $dispatcher->addSubscriber(new HttpKernel\EventListener\ResponseListener('UTF-8'));
 
-If you want out of the box support for streamed responses, subscribe
-to ``StreamedResponseListener``::
-
-    $dispatcher->addSubscriber(new HttpKernel\EventListener\StreamedResponseListener());
-
 And in your controller, return a ``StreamedResponse`` instance instead of a
 ``Response`` instance.
 
diff --git a/introduction/from_flat_php_to_symfony.rst b/introduction/from_flat_php_to_symfony.rst
index 7386f629546..3ae6a16d8a3 100644
--- a/introduction/from_flat_php_to_symfony.rst
+++ b/introduction/from_flat_php_to_symfony.rst
@@ -240,7 +240,7 @@ the ``templates/layout.php``:
 You now have a setup that will allow you to reuse the layout.
 Unfortunately, to accomplish this, you're forced to use a few ugly
 PHP functions (``ob_start()``, ``ob_get_clean()``) in the template. Symfony
-solves this using a `Templating`_ component. You'll see it in action shortly.
+solves this using `Twig`_. You'll see it in action shortly.
 
 Adding a Blog "show" Page
 -------------------------
@@ -568,9 +568,8 @@ nice way to group related pages. The controller functions are also sometimes cal
 
 The two controllers (or actions) are still lightweight. Each uses the
 :doc:`Doctrine ORM library </doctrine>` to retrieve objects from the
-database and the Templating component to render a template and return a
-``Response`` object. The ``list.html.twig`` template is now quite a bit simpler,
-and uses Twig:
+database and Twig to render a template and return a ``Response`` object.
+The ``list.html.twig`` template is now quite a bit simpler, and uses Twig:
 
 .. code-block:: html+twig
 
@@ -677,7 +676,7 @@ migrating the blog from flat PHP to Symfony has improved your life:
   :doc:`routing </routing>`, or rendering :doc:`controllers </controller>`;
 
 * Symfony gives you **access to open source tools** such as `Doctrine`_ and the
-  `Templating`_, :doc:`Security </security>`, :doc:`Form </components/form>`,
+  `Twig`_, :doc:`Security </security>`, :doc:`Form </components/form>`,
   `Validator`_ and `Translation`_ components (to name a few);
 
 * The application now enjoys **fully-flexible URLs** thanks to the Routing
@@ -694,7 +693,7 @@ A good selection of `Symfony community tools`_ can be found on GitHub.
 
 .. _`Model-View-Controller`: https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
 .. _`Doctrine`: https://www.doctrine-project.org/
-.. _Templating: https://github.com/symfony/templating
+.. _Twig: https://github.com/twigphp/twig
 .. _Translation: https://github.com/symfony/translation
 .. _`Composer`: https://getcomposer.org
 .. _`download Composer`: https://getcomposer.org/download/
diff --git a/messenger.rst b/messenger.rst
index 5d620fde6a4..bdd74c4750a 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2381,7 +2381,7 @@ will not be rolled back.
 
     If ``WhenUserRegisteredThenSendWelcomeEmail`` throws an exception, that
     exception will be wrapped into a ``DelayedMessageHandlingException``. Using
-    ``DelayedMessageHandlingException::getExceptions`` will give you all
+    ``DelayedMessageHandlingException::getWrappedExceptions`` will give you all
     exceptions that are thrown while handling a message with the
     ``DispatchAfterCurrentBusStamp``.
 

From 436f69e60f3177827ffb162bd48824433dd2acc5 Mon Sep 17 00:00:00 2001
From: Thomas Durand <thomas.durand.verjat@gmail.com>
Date: Thu, 14 Dec 2023 15:41:19 +0100
Subject: [PATCH 093/747] [HttpClient] Add `HttpOptions::addHeader` method

---
 http_client.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/http_client.rst b/http_client.rst
index 2ca591a5098..b76c8e25199 100644
--- a/http_client.rst
+++ b/http_client.rst
@@ -150,10 +150,17 @@ brings most of the available options with type-hinted getters and setters::
     $this->client = $client->withOptions(
         (new HttpOptions())
             ->setBaseUri('https://...')
+            // setHeaders() replaces *all* headers at once, and deletes the headers you do not provide
             ->setHeaders(['header-name' => 'header-value'])
+            // add or replace a single header using addHeader()
+            ->addHeader('another-header-name', 'another-header-value')
             ->toArray()
     );
 
+.. versionadded:: 7.1
+
+    The :method:`Symfony\\Component\\HttpClient\\HttpOptions::addHeader` method was introduced in Symfony 7.1.
+
 Some options are described in this guide:
 
 * `Authentication`_

From e9c7ec718bd2842d30d8886880a2ad43229dc767 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Tue, 26 Dec 2023 21:54:15 +0100
Subject: [PATCH 094/747] -

---
 http_client.rst | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/http_client.rst b/http_client.rst
index dc316fb09dc..09c8aaa28b6 100644
--- a/http_client.rst
+++ b/http_client.rst
@@ -150,7 +150,7 @@ brings most of the available options with type-hinted getters and setters::
     $this->client = $client->withOptions(
         (new HttpOptions())
             ->setBaseUri('https://...')
-            // setHeaders() replaces *all* headers at once, and deletes the headers you do not provide
+            // replaces *all* headers at once, and deletes the headers you do not provide
             ->setHeaders(['header-name' => 'header-value'])
             // add or replace a single header using addHeader()
             ->addHeader('another-header-name', 'another-header-value')
@@ -159,7 +159,8 @@ brings most of the available options with type-hinted getters and setters::
 
 .. versionadded:: 7.1
 
-    The :method:`Symfony\\Component\\HttpClient\\HttpOptions::addHeader` method was introduced in Symfony 7.1.
+    The :method:`Symfony\\Component\\HttpClient\\HttpOptions::addHeader`
+    method was introduced in Symfony 7.1.
 
 Some options are described in this guide:
 

From fc23fa3625a421d0710638ec493e7c4e8c81ef34 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Tue, 26 Dec 2023 21:59:30 +0100
Subject: [PATCH 095/747] Add missing link

---
 notifier.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/notifier.rst b/notifier.rst
index c58c777887e..e68ca298bda 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -1002,6 +1002,7 @@ is dispatched. Listeners receive a
 .. _`Slack`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Slack/README.md
 .. _`Sms77`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sms77/README.md
 .. _`SmsBiuras`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SmsBiuras/README.md
+.. _`Smsbox`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Smsbox/README.md
 .. _`Smsapi`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Smsapi/README.md
 .. _`Smsc`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Smsc/README.md
 .. _`SpotHit`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SpotHit/README.md

From 2a8e749d28a630a167a8f86d50b81fa6722c9deb Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Tue, 26 Dec 2023 21:59:55 +0100
Subject: [PATCH 096/747] -

---
 notifier.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/notifier.rst b/notifier.rst
index e68ca298bda..663398a5c0c 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -246,7 +246,8 @@ Service                                  Package                               D
 
 .. versionadded:: 7.1
 
-    The ``Bluesky``, ``Unifonic`` and ``Smsbox`` integrations were introduced in Symfony 7.1.
+    The ``Bluesky``, ``Unifonic`` and ``Smsbox`` integrations
+    were introduced in Symfony 7.1.
 
 Chatters are configured using the ``chatter_transports`` setting:
 

From 35e2703636f49277122c1d158d3c989e930cd6be Mon Sep 17 00:00:00 2001
From: Franklin LIA <46316603+lbbyf@users.noreply.github.com>
Date: Mon, 18 Dec 2023 10:51:26 +0100
Subject: [PATCH 097/747] Update routing.rst

In Symfony version 7, we don't have a loader for the annotations
---
 routing.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/routing.rst b/routing.rst
index 77b035ddd16..941c074cb0d 100644
--- a/routing.rst
+++ b/routing.rst
@@ -2600,7 +2600,7 @@ same URL, but with the HTTPS scheme.
 
 If you want to force a group of routes to use HTTPS, you can define the default
 scheme when importing them. The following example forces HTTPS on all routes
-defined as annotations:
+defined as attributes:
 
 .. configuration-block::
 

From bc95bcc4e0df59e662366c9809f636c82a5964a8 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Wed, 27 Dec 2023 09:45:56 +0100
Subject: [PATCH 098/747] Rename `addHeader` to `setHeader`

---
 http_client.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/http_client.rst b/http_client.rst
index 09c8aaa28b6..1966dfba064 100644
--- a/http_client.rst
+++ b/http_client.rst
@@ -152,14 +152,14 @@ brings most of the available options with type-hinted getters and setters::
             ->setBaseUri('https://...')
             // replaces *all* headers at once, and deletes the headers you do not provide
             ->setHeaders(['header-name' => 'header-value'])
-            // add or replace a single header using addHeader()
-            ->addHeader('another-header-name', 'another-header-value')
+            // set or replace a single header using addHeader()
+            ->setHeader('another-header-name', 'another-header-value')
             ->toArray()
     );
 
 .. versionadded:: 7.1
 
-    The :method:`Symfony\\Component\\HttpClient\\HttpOptions::addHeader`
+    The :method:`Symfony\\Component\\HttpClient\\HttpOptions::setHeader`
     method was introduced in Symfony 7.1.
 
 Some options are described in this guide:

From 78703b5aae4a0327c8fc0e5cc290f82e0e679530 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 27 Dec 2023 11:29:37 +0100
Subject: [PATCH 099/747] [Validator] Add `Charset` constraint

---
 reference/constraints/Charset.rst | 112 ++++++++++++++++++++++++++++++
 reference/constraints/map.rst.inc |   1 +
 2 files changed, 113 insertions(+)
 create mode 100644 reference/constraints/Charset.rst

diff --git a/reference/constraints/Charset.rst b/reference/constraints/Charset.rst
new file mode 100644
index 00000000000..6f8592fa5e1
--- /dev/null
+++ b/reference/constraints/Charset.rst
@@ -0,0 +1,112 @@
+Charset
+=======
+
+.. versionadded:: 7.1
+
+    The ``Charset`` constraint was introduced in Symfony 7.1.
+
+Validates that a string is encoded in a given charset.
+
+==========  =====================================================================
+Applies to  :ref:`property or method <validation-property-target>`
+Class       :class:`Symfony\\Component\\Validator\\Constraints\\Charset`
+Validator   :class:`Symfony\\Component\\Validator\\Constraints\\CharsetValidator`
+==========  =====================================================================
+
+Basic Usage
+-----------
+
+If you wanted to ensure that the ``content`` property of an ``FileDTO``
+class uses UTF-8, you could do the following:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Entity/FileDTO.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+
+        class FileDTO
+        {
+            #[Assert\Charset('UTF-8')]
+            protected string $content;
+        }
+
+    .. code-block:: yaml
+
+        # config/validator/validation.yaml
+        App\Entity\FileDTO:
+            properties:
+                content:
+                    - Charset: 'UTF-8'
+
+    .. code-block:: xml
+
+        <!-- config/validator/validation.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
+
+            <class name="App\Entity\FileDTO">
+                <property name="content">
+                    <constraint name="Charset">
+                        <option name="charset">UTF-8</option>
+                    </constraint>
+                </property>
+            </class>
+        </constraint-mapping>
+
+    .. code-block:: php
+
+        // src/Entity/FileDTO.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+        use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+        class FileDTO
+        {
+            // ...
+
+            public static function loadValidatorMetadata(ClassMetadata $metadata): void
+            {
+                $metadata->addPropertyConstraint('content', new Assert\Charset('UTF-8'));
+            }
+        }
+
+Options
+-------
+
+``encodings``
+~~~~~~~~~~~~~
+
+**type**: ``array`` | ``string`` **default**: ``[]``
+
+An encoding or a set of encodings to check against. If you pass an array of
+encodings, the validator will check if the value is encoded in *any* of the
+encodings. This option accept any value that can be passed to
+:phpfunction:`mb_detect_encoding()`.
+
+.. include:: /reference/constraints/_groups-option.rst.inc
+
+``message``
+~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``The detected encoding "{{ detected }}" does not match one of the accepted encoding: "{{ encodings }}".``
+
+This is the message that will be shown if the value does not match any of the
+accepted encodings.
+
+You can use the following parameters in this message:
+
+===================  ==============================================================
+Parameter            Description
+===================  ==============================================================
+``{{ detected }}``   The detected encoding
+``{{ encodings }}``  The accepted encodings
+===================  ==============================================================
+
+.. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/map.rst.inc b/reference/constraints/map.rst.inc
index 2fa03ac9a3e..a9692062d28 100644
--- a/reference/constraints/map.rst.inc
+++ b/reference/constraints/map.rst.inc
@@ -31,6 +31,7 @@ String Constraints
 * :doc:`PasswordStrength </reference/constraints/PasswordStrength>`
 * :doc:`CssColor </reference/constraints/CssColor>`
 * :doc:`NoSuspiciousCharacters </reference/constraints/NoSuspiciousCharacters>`
+* :doc:`Charset </reference/constraints/Charset>`
 
 Comparison Constraints
 ~~~~~~~~~~~~~~~~~~~~~~

From 17663e273ec9b29b3ad42e50ea9c5a35d8ab1c30 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Thu, 28 Dec 2023 00:12:25 +0100
Subject: [PATCH 100/747] fix typos

---
 reference/constraints/Charset.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/reference/constraints/Charset.rst b/reference/constraints/Charset.rst
index 6f8592fa5e1..5dfa7037c6b 100644
--- a/reference/constraints/Charset.rst
+++ b/reference/constraints/Charset.rst
@@ -16,7 +16,7 @@ Validator   :class:`Symfony\\Component\\Validator\\Constraints\\CharsetValidator
 Basic Usage
 -----------
 
-If you wanted to ensure that the ``content`` property of an ``FileDTO``
+If you wanted to ensure that the ``content`` property of a ``FileDTO``
 class uses UTF-8, you could do the following:
 
 .. configuration-block::
@@ -87,7 +87,7 @@ Options
 
 An encoding or a set of encodings to check against. If you pass an array of
 encodings, the validator will check if the value is encoded in *any* of the
-encodings. This option accept any value that can be passed to
+encodings. This option accepts any value that can be passed to
 :phpfunction:`mb_detect_encoding()`.
 
 .. include:: /reference/constraints/_groups-option.rst.inc

From 951328319aaf384ae93e2091a7c5dd7bb00fdfaa Mon Sep 17 00:00:00 2001
From: Dennis Fridrich <fridrich.dennis@gmail.com>
Date: Sun, 10 Dec 2023 14:57:22 +0100
Subject: [PATCH 101/747] [Notifier] Add docs of sms-sluzba.cz bridge

---
 notifier.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/notifier.rst b/notifier.rst
index 663398a5c0c..23d6c300216 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -88,6 +88,7 @@ Service             Package                                DSN
 `RingCentral`_      ``symfony/ring-central-notifier``      ``ringcentral://API_TOKEN@default?from=FROM``
 `Sendberry`_        ``symfony/sendberry-notifier``         ``sendberry://USERNAME:PASSWORD@default?auth_key=AUTH_KEY&from=FROM``
 `Sms77`_            ``symfony/sms77-notifier``             ``sms77://API_KEY@default?from=FROM``
+`SmsSluzba`_        ``symfony/sms-sluzba-notifier``        ``sms-sluzba://USERNAME:PASSWORD@default``
 `SimpleTextin`_     ``symfony/simple-textin-notifier``     ``simpletextin://API_KEY@default?from=FROM``
 `Sinch`_            ``symfony/sinch-notifier``             ``sinch://ACCOUNT_ID:AUTH_TOKEN@default?from=FROM``
 `Smsapi`_           ``symfony/smsapi-notifier``            ``smsapi://TOKEN@default?from=FROM``
@@ -110,6 +111,10 @@ Service             Package                                DSN
     via webhooks. See the :doc:`Webhook documentation </webhook>` for more
     details.
 
+.. versionadded:: 7.1
+
+    The `SmsSluzba`_ integration was introduced in Symfony 7.1.
+
 To enable a texter, add the correct DSN in your ``.env`` file and
 configure the ``texter_transports``:
 
@@ -1006,6 +1011,7 @@ is dispatched. Listeners receive a
 .. _`Smsbox`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Smsbox/README.md
 .. _`Smsapi`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Smsapi/README.md
 .. _`Smsc`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Smsc/README.md
+.. _`SmsSluzba`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SmsSluzba/README.md
 .. _`SpotHit`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SpotHit/README.md
 .. _`Telegram`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Telegram/README.md
 .. _`Telnyx`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Telnyx/README.md

From b995787767e2f356afea15b774904dc93a32f727 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Thu, 28 Dec 2023 21:57:15 +0100
Subject: [PATCH 102/747] -

---
 notifier.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/notifier.rst b/notifier.rst
index 23d6c300216..c8aa863413d 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -72,7 +72,6 @@ Service             Package                                DSN
 `GoIP`_             ``symfony/goip-notifier``              ``goip://USERNAME:PASSWORD@HOST:80?sim_slot=SIM_SLOT``
 `Infobip`_          ``symfony/infobip-notifier``           ``infobip://AUTH_TOKEN@HOST?from=FROM``
 `Iqsms`_            ``symfony/iqsms-notifier``             ``iqsms://LOGIN:PASSWORD@default?from=FROM``
-`iSendPro`_         ``symfony/isendpro-notifier``          ``isendpro://ACCOUNT_KEY_ID@default?from=FROM&no_stop=NO_STOP&sandbox=SANDBOX``
 `KazInfoTeh`_       ``symfony/kaz-info-teh-notifier``      ``kaz-info-teh://USERNAME:PASSWORD@default?sender=FROM``
 `LightSms`_         ``symfony/light-sms-notifier``         ``lightsms://LOGIN:TOKEN@default?from=PHONE``
 `Mailjet`_          ``symfony/mailjet-notifier``           ``mailjet://TOKEN@default?from=FROM``
@@ -86,16 +85,16 @@ Service             Package                                DSN
 `Plivo`_            ``symfony/plivo-notifier``             ``plivo://AUTH_ID:AUTH_TOKEN@default?from=FROM``
 `Redlink`_          ``symfony/redlink-notifier``           ``redlink://API_KEY:APP_KEY@default?from=SENDER_NAME&version=API_VERSION``
 `RingCentral`_      ``symfony/ring-central-notifier``      ``ringcentral://API_TOKEN@default?from=FROM``
+`SMSFactor`_        ``symfony/sms-factor-notifier``        ``sms-factor://TOKEN@default?sender=SENDER&push_type=PUSH_TYPE``
 `Sendberry`_        ``symfony/sendberry-notifier``         ``sendberry://USERNAME:PASSWORD@default?auth_key=AUTH_KEY&from=FROM``
-`Sms77`_            ``symfony/sms77-notifier``             ``sms77://API_KEY@default?from=FROM``
-`SmsSluzba`_        ``symfony/sms-sluzba-notifier``        ``sms-sluzba://USERNAME:PASSWORD@default``
 `SimpleTextin`_     ``symfony/simple-textin-notifier``     ``simpletextin://API_KEY@default?from=FROM``
 `Sinch`_            ``symfony/sinch-notifier``             ``sinch://ACCOUNT_ID:AUTH_TOKEN@default?from=FROM``
-`Smsapi`_           ``symfony/smsapi-notifier``            ``smsapi://TOKEN@default?from=FROM``
+`Sms77`_            ``symfony/sms77-notifier``             ``sms77://API_KEY@default?from=FROM``
 `SmsBiuras`_        ``symfony/sms-biuras-notifier``        ``smsbiuras://UID:API_KEY@default?from=FROM&test_mode=0``
+`SmsSluzba`_        ``symfony/sms-sluzba-notifier``        ``sms-sluzba://USERNAME:PASSWORD@default``
+`Smsapi`_           ``symfony/smsapi-notifier``            ``smsapi://TOKEN@default?from=FROM``
 `Smsbox`_           ``symfony/smsbox-notifier``            ``smsbox://APIKEY@default?mode=MODE&strategy=STRATEGY&sender=SENDER``
 `Smsc`_             ``symfony/smsc-notifier``              ``smsc://LOGIN:PASSWORD@default?from=FROM``
-`SMSFactor`_        ``symfony/sms-factor-notifier``        ``sms-factor://TOKEN@default?sender=SENDER&push_type=PUSH_TYPE``
 `SpotHit`_          ``symfony/spot-hit-notifier``          ``spothit://TOKEN@default?from=FROM``
 `Telnyx`_           ``symfony/telnyx-notifier``            ``telnyx://API_KEY@default?from=FROM&messaging_profile_id=MESSAGING_PROFILE_ID``
 `TurboSms`_         ``symfony/turbo-sms-notifier``         ``turbosms://AUTH_TOKEN@default?from=FROM``
@@ -103,6 +102,7 @@ Service             Package                                DSN
 `Unifonic`_         ``symfony/unifonic-notifier``          ``unifonic://APP_SID@default?from=FROM``
 `Vonage`_           ``symfony/vonage-notifier``            ``vonage://KEY:SECRET@default?from=FROM``                                                                                 yes
 `Yunpian`_          ``symfony/yunpian-notifier``           ``yunpian://APIKEY@default``
+`iSendPro`_         ``symfony/isendpro-notifier``          ``isendpro://ACCOUNT_KEY_ID@default?from=FROM&no_stop=NO_STOP&sandbox=SANDBOX``
 ==================  =====================================  ========================================================================================================================= ===============
 
 .. tip::

From 3f638192d8b781335c0d4b1165277c72eb51cd27 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Thu, 28 Dec 2023 21:57:15 +0100
Subject: [PATCH 103/747] -

---
 notifier.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/notifier.rst b/notifier.rst
index 23d6c300216..c8aa863413d 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -72,7 +72,6 @@ Service             Package                                DSN
 `GoIP`_             ``symfony/goip-notifier``              ``goip://USERNAME:PASSWORD@HOST:80?sim_slot=SIM_SLOT``
 `Infobip`_          ``symfony/infobip-notifier``           ``infobip://AUTH_TOKEN@HOST?from=FROM``
 `Iqsms`_            ``symfony/iqsms-notifier``             ``iqsms://LOGIN:PASSWORD@default?from=FROM``
-`iSendPro`_         ``symfony/isendpro-notifier``          ``isendpro://ACCOUNT_KEY_ID@default?from=FROM&no_stop=NO_STOP&sandbox=SANDBOX``
 `KazInfoTeh`_       ``symfony/kaz-info-teh-notifier``      ``kaz-info-teh://USERNAME:PASSWORD@default?sender=FROM``
 `LightSms`_         ``symfony/light-sms-notifier``         ``lightsms://LOGIN:TOKEN@default?from=PHONE``
 `Mailjet`_          ``symfony/mailjet-notifier``           ``mailjet://TOKEN@default?from=FROM``
@@ -86,16 +85,16 @@ Service             Package                                DSN
 `Plivo`_            ``symfony/plivo-notifier``             ``plivo://AUTH_ID:AUTH_TOKEN@default?from=FROM``
 `Redlink`_          ``symfony/redlink-notifier``           ``redlink://API_KEY:APP_KEY@default?from=SENDER_NAME&version=API_VERSION``
 `RingCentral`_      ``symfony/ring-central-notifier``      ``ringcentral://API_TOKEN@default?from=FROM``
+`SMSFactor`_        ``symfony/sms-factor-notifier``        ``sms-factor://TOKEN@default?sender=SENDER&push_type=PUSH_TYPE``
 `Sendberry`_        ``symfony/sendberry-notifier``         ``sendberry://USERNAME:PASSWORD@default?auth_key=AUTH_KEY&from=FROM``
-`Sms77`_            ``symfony/sms77-notifier``             ``sms77://API_KEY@default?from=FROM``
-`SmsSluzba`_        ``symfony/sms-sluzba-notifier``        ``sms-sluzba://USERNAME:PASSWORD@default``
 `SimpleTextin`_     ``symfony/simple-textin-notifier``     ``simpletextin://API_KEY@default?from=FROM``
 `Sinch`_            ``symfony/sinch-notifier``             ``sinch://ACCOUNT_ID:AUTH_TOKEN@default?from=FROM``
-`Smsapi`_           ``symfony/smsapi-notifier``            ``smsapi://TOKEN@default?from=FROM``
+`Sms77`_            ``symfony/sms77-notifier``             ``sms77://API_KEY@default?from=FROM``
 `SmsBiuras`_        ``symfony/sms-biuras-notifier``        ``smsbiuras://UID:API_KEY@default?from=FROM&test_mode=0``
+`SmsSluzba`_        ``symfony/sms-sluzba-notifier``        ``sms-sluzba://USERNAME:PASSWORD@default``
+`Smsapi`_           ``symfony/smsapi-notifier``            ``smsapi://TOKEN@default?from=FROM``
 `Smsbox`_           ``symfony/smsbox-notifier``            ``smsbox://APIKEY@default?mode=MODE&strategy=STRATEGY&sender=SENDER``
 `Smsc`_             ``symfony/smsc-notifier``              ``smsc://LOGIN:PASSWORD@default?from=FROM``
-`SMSFactor`_        ``symfony/sms-factor-notifier``        ``sms-factor://TOKEN@default?sender=SENDER&push_type=PUSH_TYPE``
 `SpotHit`_          ``symfony/spot-hit-notifier``          ``spothit://TOKEN@default?from=FROM``
 `Telnyx`_           ``symfony/telnyx-notifier``            ``telnyx://API_KEY@default?from=FROM&messaging_profile_id=MESSAGING_PROFILE_ID``
 `TurboSms`_         ``symfony/turbo-sms-notifier``         ``turbosms://AUTH_TOKEN@default?from=FROM``
@@ -103,6 +102,7 @@ Service             Package                                DSN
 `Unifonic`_         ``symfony/unifonic-notifier``          ``unifonic://APP_SID@default?from=FROM``
 `Vonage`_           ``symfony/vonage-notifier``            ``vonage://KEY:SECRET@default?from=FROM``                                                                                 yes
 `Yunpian`_          ``symfony/yunpian-notifier``           ``yunpian://APIKEY@default``
+`iSendPro`_         ``symfony/isendpro-notifier``          ``isendpro://ACCOUNT_KEY_ID@default?from=FROM&no_stop=NO_STOP&sandbox=SANDBOX``
 ==================  =====================================  ========================================================================================================================= ===============
 
 .. tip::

From d289bcb3d8190d090057cbe2ee000ec4e36c7d0b Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Thu, 28 Dec 2023 22:14:04 +0100
Subject: [PATCH 104/747] [Notifier] Add Seven.io bridge

---
 notifier.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/notifier.rst b/notifier.rst
index c8aa863413d..434b783b747 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -87,6 +87,7 @@ Service             Package                                DSN
 `RingCentral`_      ``symfony/ring-central-notifier``      ``ringcentral://API_TOKEN@default?from=FROM``
 `SMSFactor`_        ``symfony/sms-factor-notifier``        ``sms-factor://TOKEN@default?sender=SENDER&push_type=PUSH_TYPE``
 `Sendberry`_        ``symfony/sendberry-notifier``         ``sendberry://USERNAME:PASSWORD@default?auth_key=AUTH_KEY&from=FROM``
+`Seven.io`_         ``symfony/sevenio-notifier``           ``sevenio://API_KEY@default?from=FROM``
 `SimpleTextin`_     ``symfony/simple-textin-notifier``     ``simpletextin://API_KEY@default?from=FROM``
 `Sinch`_            ``symfony/sinch-notifier``             ``sinch://ACCOUNT_ID:AUTH_TOKEN@default?from=FROM``
 `Sms77`_            ``symfony/sms77-notifier``             ``sms77://API_KEY@default?from=FROM``
@@ -115,6 +116,11 @@ Service             Package                                DSN
 
     The `SmsSluzba`_ integration was introduced in Symfony 7.1.
 
+.. deprecated:: 7.1
+
+    The `Sms77`_ integration is deprecated since
+    Symfony 7.1, use the `Seven.io`_ integration instead.
+
 To enable a texter, add the correct DSN in your ``.env`` file and
 configure the ``texter_transports``:
 
@@ -1003,6 +1009,7 @@ is dispatched. Listeners receive a
 .. _`RocketChat`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/RocketChat/README.md
 .. _`SMSFactor`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SmsFactor/README.md
 .. _`Sendberry`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sendberry/README.md
+.. _`Seven.io`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sevenio/README.md
 .. _`SimpleTextin`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SimpleTextin/README.md
 .. _`Sinch`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sinch/README.md
 .. _`Slack`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Slack/README.md

From 420bf581e50dd273feebaf2fdbed523e744f387f Mon Sep 17 00:00:00 2001
From: Priyadi Iman Nurcahyo <priyadi@priyadi.net>
Date: Wed, 27 Dec 2023 20:21:30 +0700
Subject: [PATCH 105/747] Document `#[WithHttpStatus]` and `#[WithLogLevel]` on
 interfaces.

---
 reference/configuration/framework.rst | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 894cf7a82c5..2e82f352af0 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -3806,6 +3806,26 @@ the ``#[WithLogLevel]`` attribute::
     {
     }
 
+The attributes can also be added to interfaces directly::
+
+    namespace App\Exception;
+
+    use Symfony\Component\HttpKernel\Attribute\WithHttpStatus;
+
+    #[WithHttpStatus(422)]
+    interface CustomExceptionInterface
+    {
+    }
+
+    class CustomException extends \Exception implements CustomExceptionInterface
+    {
+    }
+
+.. versionadded:: 7.1
+
+    Support to use ``#[WithHttpStatus]`` and ``#[WithLogLevel]`` attributes
+    on interfaces, was introduced in Symfony 7.1.
+
 .. _`HTTP Host header attacks`: https://www.skeletonscribe.net/2013/05/practical-http-host-header-attacks.html
 .. _`Security Advisory Blog post`: https://symfony.com/blog/security-releases-symfony-2-0-24-2-1-12-2-2-5-and-2-3-3-released#cve-2013-4752-request-gethost-poisoning
 .. _`phpstorm-url-handler`: https://github.com/sanduhrs/phpstorm-url-handler

From 6a36a2217e22215deba87ff0a8c405e060516cb6 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 29 Dec 2023 08:46:14 +0100
Subject: [PATCH 106/747] [Validator] Mention support of Stringable objects in
 Charset constraint

---
 reference/constraints/Charset.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/reference/constraints/Charset.rst b/reference/constraints/Charset.rst
index 5dfa7037c6b..66bdb4c99c4 100644
--- a/reference/constraints/Charset.rst
+++ b/reference/constraints/Charset.rst
@@ -5,7 +5,8 @@ Charset
 
     The ``Charset`` constraint was introduced in Symfony 7.1.
 
-Validates that a string is encoded in a given charset.
+Validates that a string (or an object implementing the ``Stringable`` PHP interface)
+is encoded in a given charset.
 
 ==========  =====================================================================
 Applies to  :ref:`property or method <validation-property-target>`

From cf4d72446c92c2049a16b6a147abe856f627003d Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Sat, 30 Dec 2023 09:21:13 +0100
Subject: [PATCH 107/747] update the default message of the Charset constraint

---
 reference/constraints/Charset.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/constraints/Charset.rst b/reference/constraints/Charset.rst
index 66bdb4c99c4..278ea570831 100644
--- a/reference/constraints/Charset.rst
+++ b/reference/constraints/Charset.rst
@@ -96,7 +96,7 @@ encodings. This option accepts any value that can be passed to
 ``message``
 ~~~~~~~~~~~
 
-**type**: ``string`` **default**: ``The detected encoding "{{ detected }}" does not match one of the accepted encoding: "{{ encodings }}".``
+**type**: ``string`` **default**: ``The detected character encoding is invalid ({{ detected }}). Allowed encodings are {{ encodings }}.``
 
 This is the message that will be shown if the value does not match any of the
 accepted encodings.

From 09675098c807f8fbbf8be96565d1d2e2e474dcfc Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Sat, 30 Dec 2023 22:50:58 +0100
Subject: [PATCH 108/747] Update framework config

---
 reference/configuration/framework.rst | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 894cf7a82c5..50bfc03530b 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -53,13 +53,11 @@ out all the application users.
 handle_all_throwables
 ~~~~~~~~~~~~~~~~~~~~~
 
-**type**: ``boolean`` **default**: ``false``
+**type**: ``boolean`` **default**: ``true``
 
-If set to ``true``, the Symfony kernel will catch all ``\Throwable`` exceptions
+When set to ``true``, the Symfony kernel will catch all ``\Throwable`` exceptions
 thrown by the application and will turn them into HTTP responses.
 
-Starting from Symfony 7.0, the default value of this option will be ``true``.
-
 .. _configuration-framework-http_cache:
 
 http_cache
@@ -1575,11 +1573,13 @@ To see a list of all available storages, run:
 handler_id
 ..........
 
-**type**: ``string`` **default**: ``session.handler.native_file``
+**type**: ``string`` | ``null`` **default**: ``null``
+
+By default at ``null`` if ``framework.session.save_path`` is not set.
+The session handler configured by php.ini is used, unless option
+``framework.session.save_path`` is used, in which case the default is to store sessions
+using the native file session handler.
 
-The service id or DSN used for session storage. The default value ``'session.handler.native_file'``
-will let Symfony manage the sessions itself using files to store the session metadata.
-Set it to ``null`` to use the native PHP session mechanism.
 It is possible to :ref:`store sessions in a database <session-database>`,
 and also to configure the session handler with a DSN:
 
@@ -1844,7 +1844,7 @@ If not set, ``php.ini``'s `session.sid_bits_per_character`_ directive will be re
 save_path
 .........
 
-**type**: ``string`` or ``null`` **default**: ``%kernel.cache_dir%/sessions``
+**type**: ``string`` | ``null`` **default**: ``%kernel.cache_dir%/sessions``
 
 This determines the argument to be passed to the save handler. If you choose
 the default file handler, this is the path where the session files are created.
@@ -2940,7 +2940,7 @@ php_errors
 log
 ...
 
-**type**: ``boolean|int`` **default**: ``%kernel.debug%``
+**type**: ``boolean`` | ``int`` **default**: ``true``
 
 Use the application logger instead of the PHP logger for logging PHP errors.
 When an integer value is used, it also sets the log level. Those integer

From d271d42221180b45bbf01dfadc5293ac17638033 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Mon, 1 Jan 2024 12:57:07 +0100
Subject: [PATCH 109/747] fix typo

---
 reference/configuration/framework.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index ee22e85f7e8..c8686c3d7bb 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -3824,7 +3824,7 @@ The attributes can also be added to interfaces directly::
 .. versionadded:: 7.1
 
     Support to use ``#[WithHttpStatus]`` and ``#[WithLogLevel]`` attributes
-    on interfaces, was introduced in Symfony 7.1.
+    on interfaces was introduced in Symfony 7.1.
 
 .. _`HTTP Host header attacks`: https://www.skeletonscribe.net/2013/05/practical-http-host-header-attacks.html
 .. _`Security Advisory Blog post`: https://symfony.com/blog/security-releases-symfony-2-0-24-2-1-12-2-2-5-and-2-3-3-released#cve-2013-4752-request-gethost-poisoning

From 80fa0a34618d2480e6b3acce32977ea4ff143e89 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 2 Jan 2024 09:27:16 +0100
Subject: [PATCH 110/747] Minor reword

---
 reference/configuration/framework.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index a0650093bb5..f5f5f8df3f9 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -1575,10 +1575,10 @@ handler_id
 
 **type**: ``string`` | ``null`` **default**: ``null``
 
-By default at ``null`` if ``framework.session.save_path`` is not set.
-The session handler configured by php.ini is used, unless option
-``framework.session.save_path`` is used, in which case the default is to store sessions
-using the native file session handler.
+If ``framework.session.save_path`` is not set, the default value of this option
+is ``null``, which means to use the session handler configured in php.ini. If the
+``framework.session.save_path`` option is set, then Symfony stores sessions using
+the native file session handler.
 
 It is possible to :ref:`store sessions in a database <session-database>`,
 and also to configure the session handler with a DSN:

From 6b319a22eab53a36e291ef9096537abd617a7d28 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 2 Jan 2024 09:20:17 +0100
Subject: [PATCH 111/747] [Uid] Add `UuidV1::toV6()`, `UuidV1::toV7()` and
 `UuidV6::toV7()`

---
 components/uid.rst | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/components/uid.rst b/components/uid.rst
index 26fd32989a9..96dda1e149d 100644
--- a/components/uid.rst
+++ b/components/uid.rst
@@ -180,6 +180,26 @@ Use these methods to transform the UUID object into different bases::
     $uuid->toRfc4122(); // string(36) "d9e7a184-5d5b-11ea-a62a-3499710062d0"
     $uuid->toHex();     // string(34) "0xd9e7a1845d5b11eaa62a3499710062d0"
 
+Some UUID versions support being converted from one version to another::
+
+    // convert V1 to V6 or V7
+    $uuid = Uuid::v1();
+
+    $uuid->toV6(); // returns a Symfony\Component\Uid\UuidV6 instance
+    $uuid->toV7(); // returns a Symfony\Component\Uid\UuidV7 instance
+
+    // convert V6 to V7
+    $uuid = Uuid::v6();
+
+    $uuid->toV7(); // returns a Symfony\Component\Uid\UuidV7 instance
+
+.. versionadded:: 7.1
+
+    The :method:`Symfony\\Component\\Uid\\UuidV1::toV6`,
+    :method:`Symfony\\Component\\Uid\\UuidV1::toV7` and
+    :method:`Symfony\\Component\\Uid\\UuidV6::toV7`
+    methods were introduced in Symfony 7.1.
+
 Working with UUIDs
 ~~~~~~~~~~~~~~~~~~
 

From 50a296fc648774e3cab0c60331f664727424fcb7 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 2 Jan 2024 11:24:51 +0100
Subject: [PATCH 112/747] Minor tweak

---
 components/uid.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/uid.rst b/components/uid.rst
index 96dda1e149d..6e69e36a610 100644
--- a/components/uid.rst
+++ b/components/uid.rst
@@ -180,7 +180,7 @@ Use these methods to transform the UUID object into different bases::
     $uuid->toRfc4122(); // string(36) "d9e7a184-5d5b-11ea-a62a-3499710062d0"
     $uuid->toHex();     // string(34) "0xd9e7a1845d5b11eaa62a3499710062d0"
 
-Some UUID versions support being converted from one version to another::
+You can also convert some UUID versions to others::
 
     // convert V1 to V6 or V7
     $uuid = Uuid::v1();

From c9ff43ee840cfdea207b315a83c44f35ce221961 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 3 Jan 2024 09:06:43 +0100
Subject: [PATCH 113/747] [Dotenv] Add `SYMFONY_DOTENV_PATH`

---
 configuration.rst | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/configuration.rst b/configuration.rst
index 5ab7d5e2c27..4efc7d73bd9 100644
--- a/configuration.rst
+++ b/configuration.rst
@@ -932,6 +932,28 @@ get the environment variables and will not spend time parsing the ``.env`` files
     Update your deployment tools/workflow to run the ``dotenv:dump`` command after
     each deploy to improve the application performance.
 
+Store Environment Variables In Another File
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, the environment variables are stored in the ``.env`` file located
+at the root of your project. However, you can store them in another file by
+setting the ``SYMFONY_DOTENV_PATH`` environment variable to the path and
+filename of the file where the environment variables are stored. Symfony will
+then look for the environment variables in that file, but also in the local
+and environment-specific files (e.g. ``.*.local`` and
+``.*.<environment>.local``). You can find more information about this
+in the :ref:`dedicated section <configuration-multiple-env-files>`.
+
+Because this environment variable is used to find the files where you
+application environment variable are store, it must be defined at the
+system level (e.g. in your web server configuration) and not in the
+``.env`` files.
+
+.. versionadded:: 7.1
+
+    The support for the ``SYMFONY_DOTENV_PATH`` environment variable was
+    introduced in Symfony 7.1.
+
 .. _configuration-secrets:
 
 Encrypting Environment Variables (Secrets)

From e926d7cec47260fc30d8edb5d9fd659c43810b58 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 3 Jan 2024 17:58:46 +0100
Subject: [PATCH 114/747] Minor reword

---
 configuration.rst | 34 ++++++++++++++++++----------------
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/configuration.rst b/configuration.rst
index 2d02d77c771..078ec57b49f 100644
--- a/configuration.rst
+++ b/configuration.rst
@@ -932,27 +932,29 @@ get the environment variables and will not spend time parsing the ``.env`` files
     Update your deployment tools/workflow to run the ``dotenv:dump`` command after
     each deploy to improve the application performance.
 
-Store Environment Variables In Another File
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Storing Environment Variables In Other Files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 By default, the environment variables are stored in the ``.env`` file located
-at the root of your project. However, you can store them in another file by
-setting the ``SYMFONY_DOTENV_PATH`` environment variable to the path and
-filename of the file where the environment variables are stored. Symfony will
-then look for the environment variables in that file, but also in the local
-and environment-specific files (e.g. ``.*.local`` and
-``.*.<environment>.local``). You can find more information about this
-in the :ref:`dedicated section <configuration-multiple-env-files>`.
-
-Because this environment variable is used to find the files where you
-application environment variable are store, it must be defined at the
-system level (e.g. in your web server configuration) and not in the
-``.env`` files.
+at the root of your project. However, you can store them in other file by
+setting the ``SYMFONY_DOTENV_PATH`` environment variable to the absolute path of
+that custom file.
+
+Symfony will then look for the environment variables in that file, but also in
+the local and environment-specific files (e.g. ``.*.local`` and
+``.*.<environment>.local``). Read
+:ref:`how to override environment variables <configuration-multiple-env-files>`
+to learn more about this.
+
+.. caution::
+
+    The ``SYMFONY_DOTENV_PATH`` environment variable must be defined at the
+    system level (e.g. in your web server configuration) and not in any default
+    or custom ``.env`` file.
 
 .. versionadded:: 7.1
 
-    The support for the ``SYMFONY_DOTENV_PATH`` environment variable was
-    introduced in Symfony 7.1.
+    The ``SYMFONY_DOTENV_PATH`` environment variable was introduced in Symfony 7.1.
 
 .. _configuration-secrets:
 

From 597a0886e03b9a68560aa82e76465e1c6acfc444 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Sat, 6 Jan 2024 12:12:41 +0100
Subject: [PATCH 115/747] [Validator] Add  constraint

---
 reference/constraints/MacAddress.rst | 104 +++++++++++++++++++++++++++
 reference/constraints/map.rst.inc    |   1 +
 2 files changed, 105 insertions(+)
 create mode 100644 reference/constraints/MacAddress.rst

diff --git a/reference/constraints/MacAddress.rst b/reference/constraints/MacAddress.rst
new file mode 100644
index 00000000000..e13420bd832
--- /dev/null
+++ b/reference/constraints/MacAddress.rst
@@ -0,0 +1,104 @@
+MacAddress
+==========
+
+.. versionadded:: 7.1
+
+    The ``MacAddress`` constraint was introduced in Symfony 7.1.
+
+This constraint ensures that the given value is a valid MAC address (internally it
+uses the ``FILTER_VALIDATE_MAC`` option of the :phpfunction:`filter_var` PHP
+function).
+
+==========  =====================================================================
+Applies to  :ref:`property or method <validation-property-target>`
+Class       :class:`Symfony\\Component\\Validator\\Constraints\\MacAddress`
+Validator   :class:`Symfony\\Component\\Validator\\Constraints\\MacAddressValidator`
+==========  =====================================================================
+
+Basic Usage
+-----------
+
+To use the MacAddress validator, apply it to a property on an object that
+will contain a host name.
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Entity/Author.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+
+        class Author
+        {
+            #[Assert\MacAddress]
+            protected string $mac;
+        }
+
+    .. code-block:: yaml
+
+        # config/validator/validation.yaml
+        App\Entity\Author:
+            properties:
+                mac:
+                    - MacAddress: ~
+
+    .. code-block:: xml
+
+        <!-- config/validator/validation.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
+
+            <class name="App\Entity\Author">
+                <property name="max">
+                    <constraint name="MacAddress"/>
+                </property>
+            </class>
+        </constraint-mapping>
+
+    .. code-block:: php
+
+        // src/Entity/Author.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+        use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+        class Author
+        {
+            // ...
+
+            public static function loadValidatorMetadata(ClassMetadata $metadata): void
+            {
+                $metadata->addPropertyConstraint('mac', new Assert\MacAddress());
+            }
+        }
+
+.. include:: /reference/constraints/_empty-values-are-valid.rst.inc
+
+Options
+-------
+
+.. include:: /reference/constraints/_groups-option.rst.inc
+
+``message``
+~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``This is not a valid MAC address.``
+
+This is the message that will be shown if the value is not a valid MAC address.
+
+You can use the following parameters in this message:
+
+===============  ==============================================================
+Parameter            Description
+===============  ==============================================================
+``{{ value }}``  The current (invalid) value
+===============  ==============================================================
+
+.. include:: /reference/constraints/_normalizer-option.rst.inc
+
+.. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/map.rst.inc b/reference/constraints/map.rst.inc
index a9692062d28..690e98c6bf9 100644
--- a/reference/constraints/map.rst.inc
+++ b/reference/constraints/map.rst.inc
@@ -32,6 +32,7 @@ String Constraints
 * :doc:`CssColor </reference/constraints/CssColor>`
 * :doc:`NoSuspiciousCharacters </reference/constraints/NoSuspiciousCharacters>`
 * :doc:`Charset </reference/constraints/Charset>`
+* :doc:`MacAddress </reference/constraints/MacAddress>`
 
 Comparison Constraints
 ~~~~~~~~~~~~~~~~~~~~~~

From c11a4310fcd4c4c2c4e8af4354b4ae594c535478 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Sat, 6 Jan 2024 12:48:46 +0100
Subject: [PATCH 116/747] [Uid] Add AbstractUid::toString()

---
 components/uid.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/components/uid.rst b/components/uid.rst
index 6e69e36a610..e8f2f599573 100644
--- a/components/uid.rst
+++ b/components/uid.rst
@@ -179,6 +179,11 @@ Use these methods to transform the UUID object into different bases::
     $uuid->toBase58();  // string(22) "TuetYWNHhmuSQ3xPoVLv9M"
     $uuid->toRfc4122(); // string(36) "d9e7a184-5d5b-11ea-a62a-3499710062d0"
     $uuid->toHex();     // string(34) "0xd9e7a1845d5b11eaa62a3499710062d0"
+    $uuid->toString();  // string(36) "d9e7a184-5d5b-11ea-a62a-3499710062d0"
+
+.. versionadded:: 7.1
+
+    The ``toString()`` method was introduced in Symfony 7.1.
 
 You can also convert some UUID versions to others::
 

From 0ac3068bb9c905bf0233da835d498c900b2992e4 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Sat, 6 Jan 2024 12:29:15 +0100
Subject: [PATCH 117/747] [FrameworkBundle] add a private_ranges shortcut for
 trusted_proxies

---
 deployment/proxies.rst | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/deployment/proxies.rst b/deployment/proxies.rst
index e846f95a808..2ebb1bb6a8f 100644
--- a/deployment/proxies.rst
+++ b/deployment/proxies.rst
@@ -33,6 +33,8 @@ and what headers your reverse proxy uses to send information:
             # ...
             # the IP address (or range) of your proxy
             trusted_proxies: '192.0.0.1,10.0.0.0/8'
+            # shortcut for private IP address ranges of your proxy
+            trusted_proxies: 'private_ranges'
             # trust *all* "X-Forwarded-*" headers
             trusted_headers: ['x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port', 'x-forwarded-prefix']
             # or, if your proxy instead uses the "Forwarded" header
@@ -53,6 +55,8 @@ and what headers your reverse proxy uses to send information:
             <framework:config>
                 <!-- the IP address (or range) of your proxy -->
                 <framework:trusted-proxies>192.0.0.1,10.0.0.0/8</framework:trusted-proxies>
+                <!-- shortcut for private IP address ranges of your proxy -->
+                <framework:trusted-proxies>private_ranges</framework:trusted-proxies>
 
                 <!-- trust *all* "X-Forwarded-*" headers -->
                 <framework:trusted-header>x-forwarded-for</framework:trusted-header>
@@ -75,6 +79,8 @@ and what headers your reverse proxy uses to send information:
             $framework
                 // the IP address (or range) of your proxy
                 ->trustedProxies('192.0.0.1,10.0.0.0/8')
+                // shortcut for private IP address ranges of your proxy
+                ->trustedProxies('private_ranges')
                 // trust *all* "X-Forwarded-*" headers (the ! prefix means to not trust those headers)
                 ->trustedHeaders(['x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port', 'x-forwarded-prefix'])
                 // or, if your proxy instead uses the "Forwarded" header
@@ -82,6 +88,11 @@ and what headers your reverse proxy uses to send information:
             ;
         };
 
+.. versionadded:: 7.1
+
+    ``private_ranges`` as a shortcut for private IP address ranges for the
+    `trusted_proxies` option was introduced in Symfony 7.1.
+
 .. caution::
 
     Enabling the ``Request::HEADER_X_FORWARDED_HOST`` option exposes the

From d6e3cf99d576f5443a5457f3e6b5f348183089f0 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Sat, 6 Jan 2024 17:45:04 +0100
Subject: [PATCH 118/747] -

---
 deployment/proxies.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/deployment/proxies.rst b/deployment/proxies.rst
index 2ebb1bb6a8f..6d2b4e7bd52 100644
--- a/deployment/proxies.rst
+++ b/deployment/proxies.rst
@@ -91,7 +91,7 @@ and what headers your reverse proxy uses to send information:
 .. versionadded:: 7.1
 
     ``private_ranges`` as a shortcut for private IP address ranges for the
-    `trusted_proxies` option was introduced in Symfony 7.1.
+    ``trusted_proxies`` option was introduced in Symfony 7.1.
 
 .. caution::
 

From a7e57059acc12854419455b457a0cabd4cef7c41 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Sun, 7 Jan 2024 18:00:53 +0100
Subject: [PATCH 119/747] [#18757] fix merge

---
 routing.rst | 1 -
 1 file changed, 1 deletion(-)

diff --git a/routing.rst b/routing.rst
index 941c074cb0d..402a26e09e9 100644
--- a/routing.rst
+++ b/routing.rst
@@ -2610,7 +2610,6 @@ defined as attributes:
         controllers:
             resource: '../../src/Controller/'
             type: attribute
-            defaults:
             schemes: [https]
 
     .. code-block:: xml

From dc1854310e8a4d4675cbb75dc994add35d02d682 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rokas=20Mikalk=C4=97nas?= <rokas@mikalkenas.lt>
Date: Mon, 8 Jan 2024 07:36:00 +0200
Subject: [PATCH 120/747] [Messenger] Add jitter parameter to
 MultiplierRetryStrategy

---
 messenger.rst | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index 4b218d7c286..fbf0933f1be 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -986,6 +986,8 @@ this is configurable for each transport:
                             # e.g. 1 second delay, 2 seconds, 4 seconds
                             multiplier: 2
                             max_delay: 0
+                            # applies randomness to the delay that can prevent the thundering herd effect
+                            jitter: 0.1
                             # override all of this with a service that
                             # implements Symfony\Component\Messenger\Retry\RetryStrategyInterface
                             # service: null
@@ -1005,7 +1007,7 @@ this is configurable for each transport:
             <framework:config>
                 <framework:messenger>
                     <framework:transport name="async_priority_high" dsn="%env(MESSENGER_TRANSPORT_DSN)%?queue_name=high_priority">
-                        <framework:retry-strategy max-retries="3" delay="1000" multiplier="2" max-delay="0"/>
+                        <framework:retry-strategy max-retries="3" delay="1000" multiplier="2" max-delay="0" jitter="0.1"/>
                     </framework:transport>
                 </framework:messenger>
             </framework:config>
@@ -1030,6 +1032,8 @@ this is configurable for each transport:
                     // e.g. 1 second delay, 2 seconds, 4 seconds
                     ->multiplier(2)
                     ->maxDelay(0)
+                    // applies randomness to the delay that can prevent the thundering herd effect
+                    ->jitter(0.1)
                     // override all of this with a service that
                     // implements Symfony\Component\Messenger\Retry\RetryStrategyInterface
                     ->service(null)

From e72beecb26dbccb06bb49ef8af7c77ee5ed7fce9 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Mon, 8 Jan 2024 09:35:23 +0100
Subject: [PATCH 121/747] use PHP 8.2 for Symfony 7 builds

We were actually never running our test application with Symfony 7.0/7.1
as our CI config prevented Symfony 7 components to be installed:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires symfony/asset * -> satisfiable by symfony/asset[7.1.x-dev].
    - symfony/asset 7.1.x-dev requires php >=8.2 -> your php version (8.1.27) does not satisfy that requirement.
---
 .github/workflows/ci.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index af2ea3a28a7..c9eb6ae7b38 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -90,7 +90,7 @@ jobs:
           - name: Set-up PHP
             uses: shivammathur/setup-php@v2
             with:
-                php-version: 8.1
+                php-version: 8.2
                 coverage: none
 
           - name: Fetch branch from where the PR started

From 9fc538bf61f6e0d0932e1fcb4ddf853975aa8e3d Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 8 Jan 2024 09:48:40 +0100
Subject: [PATCH 122/747] Minor tweak

---
 messenger.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index fbf0933f1be..5f376ffbb31 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -987,6 +987,7 @@ this is configurable for each transport:
                             multiplier: 2
                             max_delay: 0
                             # applies randomness to the delay that can prevent the thundering herd effect
+                            # the value (between 0 and 1.0) is the percentage of 'delay' that will be added/subtracted
                             jitter: 0.1
                             # override all of this with a service that
                             # implements Symfony\Component\Messenger\Retry\RetryStrategyInterface
@@ -1033,6 +1034,7 @@ this is configurable for each transport:
                     ->multiplier(2)
                     ->maxDelay(0)
                     // applies randomness to the delay that can prevent the thundering herd effect
+                    // the value (between 0 and 1.0) is the percentage of 'delay' that will be added/subtracted
                     ->jitter(0.1)
                     // override all of this with a service that
                     // implements Symfony\Component\Messenger\Retry\RetryStrategyInterface
@@ -1040,6 +1042,10 @@ this is configurable for each transport:
             ;
         };
 
+.. versionadded:: 7.1
+
+    The ``jitter`` option was introduced in Symfony 7.1.
+
 .. tip::
 
     Symfony triggers a :class:`Symfony\\Component\\Messenger\\Event\\WorkerMessageRetriedEvent`

From 5dcaa08af2484f5ce2a3e7604433d216ffb04487 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Mon, 8 Jan 2024 09:59:28 +0100
Subject: [PATCH 123/747] update default message

---
 reference/constraints/MacAddress.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/constraints/MacAddress.rst b/reference/constraints/MacAddress.rst
index e13420bd832..952412c4061 100644
--- a/reference/constraints/MacAddress.rst
+++ b/reference/constraints/MacAddress.rst
@@ -87,7 +87,7 @@ Options
 ``message``
 ~~~~~~~~~~~
 
-**type**: ``string`` **default**: ``This is not a valid MAC address.``
+**type**: ``string`` **default**: ``This value is not a valid MAC address.``
 
 This is the message that will be shown if the value is not a valid MAC address.
 

From 26ca6ea010e453a8cfe6c6eb74d5a014a33b08fe Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 8 Jan 2024 11:03:52 +0100
Subject: [PATCH 124/747] [Validator] Added a link in a constraint description

---
 reference/constraints/MacAddress.rst | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/reference/constraints/MacAddress.rst b/reference/constraints/MacAddress.rst
index e13420bd832..cff74936c29 100644
--- a/reference/constraints/MacAddress.rst
+++ b/reference/constraints/MacAddress.rst
@@ -5,7 +5,7 @@ MacAddress
 
     The ``MacAddress`` constraint was introduced in Symfony 7.1.
 
-This constraint ensures that the given value is a valid MAC address (internally it
+This constraint ensures that the given value is a valid `MAC address`_ (internally it
 uses the ``FILTER_VALIDATE_MAC`` option of the :phpfunction:`filter_var` PHP
 function).
 
@@ -102,3 +102,5 @@ Parameter            Description
 .. include:: /reference/constraints/_normalizer-option.rst.inc
 
 .. include:: /reference/constraints/_payload-option.rst.inc
+
+.. _`MAC address`: https://en.wikipedia.org/wiki/MAC_address

From 47e0be071d55b58026214d4ebc3177b52d4fb364 Mon Sep 17 00:00:00 2001
From: Quentin Devos <4972091+Okhoshi@users.noreply.github.com>
Date: Mon, 8 Jan 2024 23:03:32 +0100
Subject: [PATCH 125/747] [FrameworkBundle] Update cache_dir config

Signed-off-by: Quentin Devos <4972091+Okhoshi@users.noreply.github.com>
---
 reference/configuration/framework.rst | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 254fe7fcbd1..2d54d54c79a 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -1511,6 +1511,19 @@ cache_dir
 The directory where routing information will be cached. Can be set to
 ``~`` (``null``) to disable route caching.
 
+.. deprecated:: 7.1
+
+    Setting the ``cache_dir`` option is deprecated since Symfony 7.1. The routes
+    are now always cached in the ``%kernel.build_dir%`` directory. If you want
+    to disable route caching, set the ``ignore_cache`` option to ``true``.
+
+ignore_cache
+............
+
+**type**: ``boolean`` **default**: ``false``
+
+When this option is set to ``true``, routing information will not be cached.
+
 secrets
 ~~~~~~~
 

From 8e5a16460e85ff5a54151ebc34a2d0fc4bb289da Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Wed, 10 Jan 2024 22:09:18 +0100
Subject: [PATCH 126/747] [Form] Add option separator to ChoiceType to use a
 custom separator after preferred choices

---
 reference/constraints/Choice.rst | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/reference/constraints/Choice.rst b/reference/constraints/Choice.rst
index 5a9c365be37..1a3e6d356f0 100644
--- a/reference/constraints/Choice.rst
+++ b/reference/constraints/Choice.rst
@@ -389,3 +389,25 @@ Parameter        Description
 ===============  ==============================================================
 
 .. include:: /reference/constraints/_payload-option.rst.inc
+
+``separator``
+~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``-------------------``
+
+This option allows you to customize separator after preferred choices.
+
+.. versionadded:: 7.1
+
+    The ``separator`` option was introduced in Symfony 7.1.
+
+``separator_html``
+~~~~~~~~~~~~~~~~~~
+
+**type**: ``boolean`` **default**: ``false``
+
+If this option is true, `separator`_ option will be display as HTML instead of text
+
+.. versionadded:: 7.1
+
+    The ``separator_html`` option was introduced in Symfony 7.1.

From dcd25e7ca2275cb511cf7b0d65ee551661bcf5fe Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 3 Jan 2024 08:49:32 +0100
Subject: [PATCH 127/747] [Contracts][DependencyInjection] Mention that
 locators are traversable

---
 .../service_subscribers_locators.rst          | 31 +++++++++++++++----
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst
index 3db82ad3007..897a82f8195 100644
--- a/service_container/service_subscribers_locators.rst
+++ b/service_container/service_subscribers_locators.rst
@@ -110,17 +110,36 @@ in the service subscriber::
     that you have :ref:`autoconfigure <services-autoconfigure>` enabled. You
     can also manually add the ``container.service_subscriber`` tag.
 
-The injected service is an instance of :class:`Symfony\\Component\\DependencyInjection\\ServiceLocator`
-which implements both the PSR-11 ``ContainerInterface`` and :class:`Symfony\\Contracts\\Service\\ServiceProviderInterface`.
-It is also a callable and a countable::
+A service locator is a PSR11 container that contains a set of services,
+but only instantiates them when they are actually used. Let's take a closer
+look at this part::
+
+    // ...
+    $handler = $this->locator->get($commandClass);
+
+    return $handler->handle($command);
+
+In the example above, the ``$handler`` service is only instantiated when the
+``$this->locator->get($commandClass)`` method is called.
+
+You can also type-hint the service locator argument with
+:class:`Symfony\\Contracts\\Service\\ServiceCollectionInterface` instead of
+:class:`Psr\\Container\\ContainerInterface`. By doing so, you'll be able to
+count and iterate over the services of the locator::
 
     // ...
     $numberOfHandlers = count($this->locator);
     $nameOfHandlers = array_keys($this->locator->getProvidedServices());
-    // ...
-    $handler = ($this->locator)($commandClass);
 
-    return $handler->handle($command);
+    // you can iterate through all services of the locator
+    foreach ($this->locator as $serviceId => $service) {
+        // do something with the service, the service id or both
+    }
+
+.. versionadded:: 7.1
+
+    The :class:`Symfony\\Contracts\\Service\\ServiceCollectionInterface` was
+    introduced in Symfony 7.1.
 
 Including Services
 ------------------

From a7f5f3062f976017cd516aeea68bddd3f42ce664 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 11 Jan 2024 13:34:37 +0100
Subject: [PATCH 128/747] Tweak

---
 reference/constraints/Choice.rst | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/reference/constraints/Choice.rst b/reference/constraints/Choice.rst
index 1a3e6d356f0..8bafaaede7b 100644
--- a/reference/constraints/Choice.rst
+++ b/reference/constraints/Choice.rst
@@ -395,7 +395,9 @@ Parameter        Description
 
 **type**: ``string`` **default**: ``-------------------``
 
-This option allows you to customize separator after preferred choices.
+This option allows you to customize the visual separator shown after the preferred
+choices. You can use HTML elements like ``<hr>`` to display a more modern separator,
+but you'll also need to set the `separator_html`_ option to ``true``.
 
 .. versionadded:: 7.1
 
@@ -406,7 +408,9 @@ This option allows you to customize separator after preferred choices.
 
 **type**: ``boolean`` **default**: ``false``
 
-If this option is true, `separator`_ option will be display as HTML instead of text
+If this option is true, the `separator`_ option will be displayed as HTML instead
+of text. This is useful when using HTML elements (e.g. ``<hr>``) as a more modern
+visual separator.
 
 .. versionadded:: 7.1
 

From ee5e28f3c5a67aeb72c73e115d0bb95edb97d6bb Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 12 Jan 2024 16:56:22 +0100
Subject: [PATCH 129/747] Tweak

---
 service_container/service_subscribers_locators.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst
index 897a82f8195..31a9fa55f3b 100644
--- a/service_container/service_subscribers_locators.rst
+++ b/service_container/service_subscribers_locators.rst
@@ -110,16 +110,15 @@ in the service subscriber::
     that you have :ref:`autoconfigure <services-autoconfigure>` enabled. You
     can also manually add the ``container.service_subscriber`` tag.
 
-A service locator is a PSR11 container that contains a set of services,
-but only instantiates them when they are actually used. Let's take a closer
-look at this part::
+A service locator is a `PSR-11 container`_ that contains a set of services,
+but only instantiates them when they are actually used. Consider the following code::
 
     // ...
     $handler = $this->locator->get($commandClass);
 
     return $handler->handle($command);
 
-In the example above, the ``$handler`` service is only instantiated when the
+In this example, the ``$handler`` service is only instantiated when the
 ``$this->locator->get($commandClass)`` method is called.
 
 You can also type-hint the service locator argument with
@@ -1066,3 +1065,4 @@ Another alternative is to mock it using ``PHPUnit``::
     // ...
 
 .. _`Command pattern`: https://en.wikipedia.org/wiki/Command_pattern
+.. _`PSR-11 container`: https://www.php-fig.org/psr/psr-11/

From 1bd553588da3450112c6e51f93baa29cf9cb0f1f Mon Sep 17 00:00:00 2001
From: HypeMC <hypemc@gmail.com>
Date: Fri, 12 Jan 2024 19:30:48 +0100
Subject: [PATCH 130/747] [Cache] Document using DSN with PDOAdapter

---
 cache.rst | 29 ++++++++---------------------
 1 file changed, 8 insertions(+), 21 deletions(-)

diff --git a/cache.rst b/cache.rst
index 98ec11123fc..d1da8c87560 100644
--- a/cache.rst
+++ b/cache.rst
@@ -133,12 +133,7 @@ Some of these adapters could be configured via shortcuts.
                 default_psr6_provider: 'app.my_psr6_service'
                 default_redis_provider: 'redis://localhost'
                 default_memcached_provider: 'memcached://localhost'
-                default_pdo_provider: 'app.my_pdo_service'
-
-        services:
-            app.my_pdo_service:
-                class: \PDO
-                arguments: ['pgsql:host=localhost']
+                default_pdo_provider: 'pgsql:host=localhost'
 
     .. code-block:: xml
 
@@ -159,24 +154,17 @@ Some of these adapters could be configured via shortcuts.
                     default-psr6-provider="app.my_psr6_service"
                     default-redis-provider="redis://localhost"
                     default-memcached-provider="memcached://localhost"
-                    default-pdo-provider="app.my_pdo_service"
+                    default-pdo-provider="pgsql:host=localhost"
                 />
             </framework:config>
-
-            <services>
-                <service id="app.my_pdo_service" class="\PDO">
-                    <argument>pgsql:host=localhost</argument>
-                </service>
-            </services>
         </container>
 
     .. code-block:: php
 
         // config/packages/cache.php
-        use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
         use Symfony\Config\FrameworkConfig;
 
-        return static function (FrameworkConfig $framework, ContainerConfigurator $container): void {
+        return static function (FrameworkConfig $framework): void {
             $framework->cache()
                 // Only used with cache.adapter.filesystem
                 ->directory('%kernel.cache_dir%/pools')
@@ -185,15 +173,14 @@ Some of these adapters could be configured via shortcuts.
                 ->defaultPsr6Provider('app.my_psr6_service')
                 ->defaultRedisProvider('redis://localhost')
                 ->defaultMemcachedProvider('memcached://localhost')
-                ->defaultPdoProvider('app.my_pdo_service')
-            ;
-
-            $container->services()
-                ->set('app.my_pdo_service', \PDO::class)
-                ->args(['pgsql:host=localhost'])
+                ->defaultPdoProvider('pgsql:host=localhost')
             ;
         };
 
+.. versionadded:: 7.1
+
+    Using a DSN as the provider for the PDO adapter was introduced in Symfony 7.1.
+
 .. _cache-create-pools:
 
 Creating Custom (Namespaced) Pools

From f3ca92f7a685928b9f1a5895a584f0dce0981ecc Mon Sep 17 00:00:00 2001
From: Simon <smn.andre@gmail.com>
Date: Mon, 15 Jan 2024 09:15:18 +0100
Subject: [PATCH 131/747] [Validator] Fix mb_detect_encoding link in Charset

Fix mb_detect_encoding link sending to 404 ( https://www.php.net/manual/en/function.mb-detect-encoding().php )
---
 reference/constraints/Charset.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/constraints/Charset.rst b/reference/constraints/Charset.rst
index 278ea570831..4f1a260356f 100644
--- a/reference/constraints/Charset.rst
+++ b/reference/constraints/Charset.rst
@@ -89,7 +89,7 @@ Options
 An encoding or a set of encodings to check against. If you pass an array of
 encodings, the validator will check if the value is encoded in *any* of the
 encodings. This option accepts any value that can be passed to
-:phpfunction:`mb_detect_encoding()`.
+:phpfunction:`mb_detect_encoding`.
 
 .. include:: /reference/constraints/_groups-option.rst.inc
 

From 43862c49f30e0428d6c02fa5bd63cb2dea34fce1 Mon Sep 17 00:00:00 2001
From: Maxime Doutreluingne <maxime.doutreluingne@gmail.com>
Date: Sat, 30 Dec 2023 16:21:22 +0100
Subject: [PATCH 132/747] [Form] Add `model_type` option to `MoneyType`

---
 reference/forms/types/money.rst | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/reference/forms/types/money.rst b/reference/forms/types/money.rst
index 9f98b49158b..65f24ac93a3 100644
--- a/reference/forms/types/money.rst
+++ b/reference/forms/types/money.rst
@@ -76,6 +76,18 @@ If set to ``true``, the HTML input will be rendered as a native HTML5
 
     As HTML5 number format is normalized, it is incompatible with ``grouping`` option.
 
+model_type
+~~~~~~~~~~
+
+**type**: ``string`` **default**: ``float``
+
+If, for some reason, you need the value to be converted to an ``integer`` instead of a ``float``,
+you can set the option value to ``integer``.
+
+.. versionadded:: 7.1
+
+    The ``model_type`` option was introduced in Symfony 7.1.
+
 scale
 ~~~~~
 

From 6b55e576c16edbd75dd2477435b52636cf3567cd Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 15 Jan 2024 13:27:16 +0100
Subject: [PATCH 133/747] Minor reword

---
 reference/forms/types/money.rst | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/reference/forms/types/money.rst b/reference/forms/types/money.rst
index 65f24ac93a3..8e2130a5909 100644
--- a/reference/forms/types/money.rst
+++ b/reference/forms/types/money.rst
@@ -81,8 +81,9 @@ model_type
 
 **type**: ``string`` **default**: ``float``
 
-If, for some reason, you need the value to be converted to an ``integer`` instead of a ``float``,
-you can set the option value to ``integer``.
+By default, the money value is converted to a ``float`` PHP type. If you need the
+value to be converted into an integer (e.g. because some library needs money
+values stored in cents as integers) set this option to ``integer``.
 
 .. versionadded:: 7.1
 

From cf8cc5beeadda756a679875593b7fc08ef169b7b Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 16 Jan 2024 13:19:19 +0100
Subject: [PATCH 134/747] [Scheduler] Remove some unneeded versionadded
 directives

---
 scheduler.rst | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/scheduler.rst b/scheduler.rst
index 8e172412559..18d0f60fe69 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -1,10 +1,6 @@
 Scheduler
 =========
 
-.. versionadded:: 6.3
-
-    The Scheduler component was introduced in Symfony 6.3
-
 The scheduler component manages task scheduling within your PHP application, like
 running a task each night at 3 AM, every two weeks except for holidays or any
 other custom schedule you might need.
@@ -143,10 +139,6 @@ It uses the same syntax as the `cron command-line utility`_::
     // optionally you can define the timezone used by the cron expression
     RecurringMessage::cron('* * * * *', new Message(), new \DateTimeZone('Africa/Malabo'));
 
-.. versionadded:: 6.4
-
-    The feature to define the cron timezone was introduced in Symfony 6.4.
-
 Before using it, you must install the following dependency:
 
 .. code-block:: terminal
@@ -266,9 +258,9 @@ the Messenger component:
 .. image:: /_images/components/scheduler/generate_consume.png
     :alt: Symfony Scheduler - generate and consume
 
-.. versionadded:: 6.4
+.. tip::
 
-    Since version 6.4, you can define your messages via a ``callback`` via the
+    You can also define your messages via a ``callback`` using the
     :class:`Symfony\\Component\\Scheduler\\Trigger\\CallbackMessageProvider`.
 
 Debugging the Schedule
@@ -300,10 +292,6 @@ recurring messages. You can narrow down the list to a specific schedule:
     # use the --all option to also display the terminated recurring messages
     $ php bin/console --all
 
-.. versionadded:: 6.4
-
-    The ``--date`` and ``--all`` options were introduced in Symfony 6.4.
-
 Efficient management with Symfony Scheduler
 -------------------------------------------
 

From 667d3af3aada3beccd155985f939f4008e35350c Mon Sep 17 00:00:00 2001
From: Mathieu Santostefano <msantostefano@protonmail.com>
Date: Wed, 17 Jan 2024 10:00:36 +0100
Subject: [PATCH 135/747] Add Resend bridge documentation

---
 mailer.rst  | 7 +++++++
 webhook.rst | 1 +
 2 files changed, 8 insertions(+)

diff --git a/mailer.rst b/mailer.rst
index dc981437e3e..37a955efe42 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -110,6 +110,7 @@ Service               Install with                                    Webhook su
 `MailerSend`_         ``composer require symfony/mailer-send-mailer``
 `Mandrill`_           ``composer require symfony/mailchimp-mailer``
 `Postmark`_           ``composer require symfony/postmark-mailer``    yes
+`Resend`_             ``composer require symfony/resend-mailer``      yes
 `Scaleway`_           ``composer require symfony/scaleway-mailer``
 `SendGrid`_           ``composer require symfony/sendgrid-mailer``    yes
 ===================== =============================================== ===============
@@ -208,6 +209,10 @@ party provider:
 |                        | - HTTP n/a                                          |
 |                        | - API postmark+api://KEY@default                    |
 +------------------------+-----------------------------------------------------+
+| `Resend`_              | - SMTP resend+smtp://resend:API_KEY@default         |
+|                        | - HTTP n/a                                          |
+|                        | - API resend+api://API_KEY@default                  |
++------------------------+-----------------------------------------------------+
 | `Scaleway`_            | - SMTP scaleway+smtp://PROJECT_ID:API_KEY@default   |
 |                        | - HTTP n/a                                          |
 |                        | - API scaleway+api://PROJECT_ID:API_KEY@default     |
@@ -1503,6 +1508,7 @@ The following transports currently support tags and metadata:
 The following transports only support tags:
 
 * MailPace
+* Resend
 
 The following transports only support metadata:
 
@@ -1847,6 +1853,7 @@ the :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\MailerAssertionsTrait`::
 .. _`OpenSSL PHP extension`: https://www.php.net/manual/en/book.openssl.php
 .. _`PEM encoded`: https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail
 .. _`Postmark`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Postmark/README.md
+.. _`Resend`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Resend/README.md
 .. _`RFC 3986`: https://www.ietf.org/rfc/rfc3986.txt
 .. _`S/MIME`: https://en.wikipedia.org/wiki/S/MIME
 .. _`Scaleway`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Scaleway/README.md
diff --git a/webhook.rst b/webhook.rst
index d6e14f12805..32567bfe29d 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -82,6 +82,7 @@ Brevo          ``mailer.webhook.request_parser.brevo``
 Mailgun        ``mailer.webhook.request_parser.mailgun``
 Mailjet        ``mailer.webhook.request_parser.mailjet``
 Postmark       ``mailer.webhook.request_parser.postmark``
+Resend         ``mailer.webhook.request_parser.resend``
 Sendgrid       ``mailer.webhook.request_parser.sendgrid``
 ============== ==========================================
 

From 0d779a50c6b458f42cfb63751869fc3f56f3a245 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 17 Jan 2024 10:29:19 +0100
Subject: [PATCH 136/747] [Scheduler] Remove unneded versionadded directives

---
 scheduler.rst | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/scheduler.rst b/scheduler.rst
index e51e8243af3..3d04d8c0a58 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -160,12 +160,6 @@ methods::
     $trigger->inner(); // CronExpressionTrigger
     $trigger->decorators(); // [ExcludeTimeTrigger, JitterTrigger]
 
-.. versionadded:: 6.4
-
-    The :method:`Symfony\\Component\\Scheduler\\Trigger\\AbstractDecoratedTrigger::inner`
-    and :method:`Symfony\\Component\\Scheduler\\Trigger\\AbstractDecoratedTrigger::decorators`
-    methods were introduced in Symfony 6.4.
-
 Most of them can be created via the :class:`Symfony\\Component\\Scheduler\\RecurringMessage`
 class, as shown in the following examples.
 

From c19e8dffb5a671eef5ae3f452b4bd3a44066d2e1 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 18 Jan 2024 10:56:52 +0100
Subject: [PATCH 137/747] Updated the versionadded directive

---
 mailer.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mailer.rst b/mailer.rst
index 37a955efe42..3d49efea597 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -117,7 +117,7 @@ Service               Install with                                    Webhook su
 
 .. versionadded:: 7.1
 
-    The Azure integration was introduced in Symfony 7.1.
+    The Azure and Resend integrations were introduced in Symfony 7.1.
 
 .. note::
 

From 78ef5d52d16d58f7b24db4939f8b78e76f458d67 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 18 Jan 2024 10:58:00 +0100
Subject: [PATCH 138/747] [Webhook] Added a missing versionadded directive

---
 webhook.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/webhook.rst b/webhook.rst
index 32567bfe29d..05885602074 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -86,6 +86,10 @@ Resend         ``mailer.webhook.request_parser.resend``
 Sendgrid       ``mailer.webhook.request_parser.sendgrid``
 ============== ==========================================
 
+.. versionadded:: 7.1
+
+    The Resend webhook was introduced in Symfony 7.1.
+
 Set up the webhook in the third-party mailer. For Mailgun, you can do this
 in the control panel. As URL, make sure to use the ``/webhook/mailer_mailgun``
 path behind the domain you're using.

From 617249b4c4d67f62e8133bc9b007e390f673b017 Mon Sep 17 00:00:00 2001
From: Stefan Doorn <stefan@efectos.nl>
Date: Mon, 22 Jan 2024 11:02:12 +0100
Subject: [PATCH 139/747] [Messenger] Clarify
 UnrecoverableMessageHandlingException message going to failure transport

---
 messenger.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index 0f1c00baae4..43a7f256343 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1044,6 +1044,12 @@ and should not be retried. If you throw
 :class:`Symfony\\Component\\Messenger\\Exception\\UnrecoverableMessageHandlingException`,
 the message will not be retried.
 
+.. note::
+
+    Messages that will not be retried, will still show up in the configured failure transport.
+    If you want to avoid that, consider handling the error yourself and let the handler
+    successfully end.
+
 Forcing Retrying
 ~~~~~~~~~~~~~~~~
 

From 56b46c7cdc2b8b1865ee65e27dacae36690a303f Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Wed, 24 Jan 2024 22:40:33 +0100
Subject: [PATCH 140/747] -

---
 webhook.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/webhook.rst b/webhook.rst
index 29d2eea0849..0b8d2514a26 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -27,6 +27,7 @@ Brevo          ``mailer.webhook.request_parser.brevo``
 Mailgun        ``mailer.webhook.request_parser.mailgun``
 Mailjet        ``mailer.webhook.request_parser.mailjet``
 Postmark       ``mailer.webhook.request_parser.postmark``
+Resend         ``mailer.webhook.request_parser.resend``
 Sendgrid       ``mailer.webhook.request_parser.sendgrid``
 ============== ==========================================
 
@@ -34,6 +35,10 @@ Sendgrid       ``mailer.webhook.request_parser.sendgrid``
 
     The support for Brevo, Mailjet and Sendgrid was introduced in Symfony 6.4.
 
+.. versionadded:: 7.1
+
+    The support for Resend was introduced in Symfony 7.1.
+
 .. note::
 
     Install the third-party mailer provider you want to use as described in the

From ca3da8b3763f01954e4ad6ecaba02aac285f602c Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Wed, 24 Jan 2024 22:40:44 +0100
Subject: [PATCH 141/747] -

---
 webhook.rst | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/webhook.rst b/webhook.rst
index 29d2eea0849..37422b75542 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -30,10 +30,6 @@ Postmark       ``mailer.webhook.request_parser.postmark``
 Sendgrid       ``mailer.webhook.request_parser.sendgrid``
 ============== ==========================================
 
-.. versionadded:: 6.4
-
-    The support for Brevo, Mailjet and Sendgrid was introduced in Symfony 6.4.
-
 .. note::
 
     Install the third-party mailer provider you want to use as described in the

From 3ee6a7fcb5baac802e7602678143ee2e7b42d563 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 3 Jan 2024 18:35:45 +0100
Subject: [PATCH 142/747] [DotEnv] Fix incorrect way to modify .env path

---
 configuration.rst | 41 ++++++++++++++++++++++++++++++++---------
 1 file changed, 32 insertions(+), 9 deletions(-)

diff --git a/configuration.rst b/configuration.rst
index 078ec57b49f..24eebb1fa00 100644
--- a/configuration.rst
+++ b/configuration.rst
@@ -936,9 +936,38 @@ Storing Environment Variables In Other Files
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 By default, the environment variables are stored in the ``.env`` file located
-at the root of your project. However, you can store them in other file by
-setting the ``SYMFONY_DOTENV_PATH`` environment variable to the absolute path of
-that custom file.
+at the root of your project. However, you can store them in other files in
+multiple ways.
+
+If you use the :doc:`Runtime component </components/runtime>`, the dotenv
+path is part of the options you can set in your ``composer.json`` file:
+
+.. code-block:: json
+
+      {
+          // ...
+          "extra": {
+              // ...
+              "runtime": {
+                  "dotenv_path": "my/custom/path/to/.env"
+              }
+          }
+      }
+
+You can also set the ``SYMFONY_DOTENV_PATH`` environment variable at system
+level (e.g. in your web server configuration or in your Dockerfile):
+
+.. code-block:: bash
+
+    # .env (or .env.local)
+    SYMFONY_DOTENV_PATH=my/custom/path/to/.env
+
+Finally, you can directly invoke the ``Dotenv`` class in your
+``bootstrap.php`` file or any other file of your application::
+
+    use Symfony\Component\Dotenv\Dotenv;
+
+    (new Dotenv())->bootEnv(dirname(__DIR__).'my/custom/path/to/.env');
 
 Symfony will then look for the environment variables in that file, but also in
 the local and environment-specific files (e.g. ``.*.local`` and
@@ -946,12 +975,6 @@ the local and environment-specific files (e.g. ``.*.local`` and
 :ref:`how to override environment variables <configuration-multiple-env-files>`
 to learn more about this.
 
-.. caution::
-
-    The ``SYMFONY_DOTENV_PATH`` environment variable must be defined at the
-    system level (e.g. in your web server configuration) and not in any default
-    or custom ``.env`` file.
-
 .. versionadded:: 7.1
 
     The ``SYMFONY_DOTENV_PATH`` environment variable was introduced in Symfony 7.1.

From ead19d00068fc1a6f22431cf3e71bc452dbc4248 Mon Sep 17 00:00:00 2001
From: Radoslaw Kowalewski <git@srsbiz.pl>
Date: Tue, 30 Jan 2024 20:36:30 +0100
Subject: [PATCH 143/747] [Mailer][Smtp] Document 'auto_tls' param

---
 mailer.rst | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/mailer.rst b/mailer.rst
index 07f341cf508..cf17a55a6e2 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -347,6 +347,30 @@ may be specified as SHA1 or MD5 hash::
 
     $dsn = 'smtp://user:pass@smtp.example.com?peer_fingerprint=6A1CF3B08D175A284C30BC10DE19162307C7286E';
 
+Disabling automatic TLS
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 7.1
+
+    Disabling automatic TLS was introduced in Symfony 7.1.
+
+By default, mailer will check if OpenSSL extension is enabled and if SMTP server
+is capable of STARTTLS, it will issue this command to enable encryption on stream.
+This behavior can be turned off by calling ``setAutoTls(false)`` on ``EsmtpTransport``
+instance, or by setting ``auto_tls`` option in DSN::
+
+    $dsn = 'smtp://user:pass@10.0.0.25?auto_tls=false';
+
+.. caution::
+
+    It's not recommended to disable TLS while connecting to SMTP server over
+    internet, but it can be useful when both application and SMTP server are in
+    secured network, where there is no need for additional encryption.
+
+.. note::
+
+    This setting works only when ``smtp://`` protocol is used.
+
 Overriding default SMTP authenticators
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From c34a612a3ed938ffd8aae847507221504a199366 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 31 Jan 2024 10:13:25 +0100
Subject: [PATCH 144/747] Minor tweak

---
 mailer.rst | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index cf17a55a6e2..8f48bd355fa 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -347,29 +347,29 @@ may be specified as SHA1 or MD5 hash::
 
     $dsn = 'smtp://user:pass@smtp.example.com?peer_fingerprint=6A1CF3B08D175A284C30BC10DE19162307C7286E';
 
-Disabling automatic TLS
+Disabling Automatic TLS
 ~~~~~~~~~~~~~~~~~~~~~~~
 
 .. versionadded:: 7.1
 
-    Disabling automatic TLS was introduced in Symfony 7.1.
+    The option to disable automatic TLS was introduced in Symfony 7.1.
 
-By default, mailer will check if OpenSSL extension is enabled and if SMTP server
-is capable of STARTTLS, it will issue this command to enable encryption on stream.
-This behavior can be turned off by calling ``setAutoTls(false)`` on ``EsmtpTransport``
-instance, or by setting ``auto_tls`` option in DSN::
+By default, the Mailer component will use encryption when the OpenSSL extension
+is enabled and the SMTP server supports ``STARTTLS``. This behavior can be turned
+off by calling ``setAutoTls(false)`` on the ``EsmtpTransport`` instance, or by
+setting the ``auto_tls`` option to ``false`` in the DSN::
 
     $dsn = 'smtp://user:pass@10.0.0.25?auto_tls=false';
 
 .. caution::
 
-    It's not recommended to disable TLS while connecting to SMTP server over
-    internet, but it can be useful when both application and SMTP server are in
-    secured network, where there is no need for additional encryption.
+    It's not recommended to disable TLS while connecting to an SMTP server over
+    the Internet, but it can be useful when both the application and the SMTP
+    server are in a secured network, where there is no need for additional encryption.
 
 .. note::
 
-    This setting works only when ``smtp://`` protocol is used.
+    This setting only works when the ``smtp://`` protocol is used.
 
 Overriding default SMTP authenticators
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

From 5495c1d47846e784ad0f5e7066d39d4db1385798 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Szymon=20Kami=C5=84ski?= <kaminskisj@gmail.com>
Date: Sat, 3 Feb 2024 14:59:16 +0100
Subject: [PATCH 145/747] [Serializer] Document DateTimeNormalizer::CAST_KEY
 context option

---
 components/serializer.rst | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/components/serializer.rst b/components/serializer.rst
index dce30b8932b..0dbd223877d 100644
--- a/components/serializer.rst
+++ b/components/serializer.rst
@@ -820,8 +820,14 @@ The Serializer component provides several built-in normalizers:
 
 :class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeNormalizer`
     This normalizer converts :phpclass:`DateTimeInterface` objects (e.g.
-    :phpclass:`DateTime` and :phpclass:`DateTimeImmutable`) into strings.
-    By default, it uses the `RFC3339`_ format.
+    :phpclass:`DateTime` and :phpclass:`DateTimeImmutable`) into strings,
+    integers or floats. By default, it converts them to strings using the `RFC3339`_ format.
+    To convert the objects to integers or floats, set the serializer context option
+    ``DateTimeNormalizer::CAST_KEY`` to ``int`` or ``float``.
+
+.. versionadded:: 7.1
+
+    ``DateTimeNormalizer::CAST_KEY`` context option was introduced in Symfony 7.1.
 
 :class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeZoneNormalizer`
     This normalizer converts :phpclass:`DateTimeZone` objects into strings that

From 7edd5d171de559b4fa471a961c3a8b5e6143978c Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Sun, 4 Feb 2024 20:45:39 +0100
Subject: [PATCH 146/747] [ExpressionLanguage] Add min and max php functions

---
 reference/formats/expression_language.rst | 28 +++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/reference/formats/expression_language.rst b/reference/formats/expression_language.rst
index 6c9b1bffe42..9a3e78ef485 100644
--- a/reference/formats/expression_language.rst
+++ b/reference/formats/expression_language.rst
@@ -120,6 +120,8 @@ following functions by default:
 
 * ``constant()``
 * ``enum()``
+* ``min()``
+* ``max()``
 
 ``constant()`` function
 ~~~~~~~~~~~~~~~~~~~~~~~
@@ -167,6 +169,32 @@ This function will return the case of an enumeration::
 
 This will print out ``true``.
 
+``min()`` function
+~~~~~~~~~~~~~~~~~~
+
+This function will return the lowest value::
+
+    var_dump($expressionLanguage->evaluate(
+        'min(1, 2, 3)'
+    ));
+
+This will print out ``1``.
+
+``max()`` function
+~~~~~~~~~~~~~~~~~~
+
+This function will return the highest value::
+
+    var_dump($expressionLanguage->evaluate(
+        'max(1, 2, 3)'
+    ));
+
+This will print out ``3``.
+
+.. versionadded:: 7.1
+
+    The ``min()`` and ``max()`` functions were introduced in Symfony 7.1.
+
 .. tip::
 
     To read how to register your own functions to use in an expression, see

From ff7350028574a6585ff666f884b9fa882437f855 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Sun, 4 Feb 2024 20:52:37 +0100
Subject: [PATCH 147/747] [Mailer][Webhook] Mailersend webhook remote event

---
 webhook.rst | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/webhook.rst b/webhook.rst
index e423a55e524..0e975860055 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -20,20 +20,21 @@ receive webhook calls from this provider.
 
 Currently, the following third-party mailer providers support webhooks:
 
-============== ==========================================
+============== ============================================
 Mailer Service Parser service name
-============== ==========================================
+============== ============================================
 Brevo          ``mailer.webhook.request_parser.brevo``
+MailerSend     ``mailer.webhook.request_parser.mailersend``
 Mailgun        ``mailer.webhook.request_parser.mailgun``
 Mailjet        ``mailer.webhook.request_parser.mailjet``
 Postmark       ``mailer.webhook.request_parser.postmark``
 Resend         ``mailer.webhook.request_parser.resend``
 Sendgrid       ``mailer.webhook.request_parser.sendgrid``
-============== ==========================================
+============== ============================================
 
 .. versionadded:: 7.1
 
-    The support for Resend was introduced in Symfony 7.1.
+    The support for ``Resend`` and ``MailerSend`` were introduced in Symfony 7.1.
 
 .. note::
 

From 22ad2d951a2e899f89fe5af4f8078f2de5b2e466 Mon Sep 17 00:00:00 2001
From: Daniel Burger <48986191+danielburger1337@users.noreply.github.com>
Date: Sat, 3 Feb 2024 14:26:00 +0100
Subject: [PATCH 148/747] Document `secrets:reveal` command

---
 configuration/secrets.rst | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/configuration/secrets.rst b/configuration/secrets.rst
index 653bd92f611..089f7da2892 100644
--- a/configuration/secrets.rst
+++ b/configuration/secrets.rst
@@ -166,6 +166,22 @@ secrets' values by passing the ``--reveal`` option:
       DATABASE_PASSWORD   "my secret"
      ------------------- ------------ -------------
 
+Reveal Existing Secrets
+-----------------------
+
+If you have the **decryption key**, the ``secrets:reveal`` command allows
+you to reveal a single secrets value.
+
+.. code-block:: terminal
+
+    $ php bin/console secrets:reveal DATABASE_PASSWORD
+
+     my secret
+
+.. versionadded:: 7.1
+
+    The ``secrets:reveal`` command was introduced in Symfony 7.1.
+
 Remove Secrets
 --------------
 

From d22ad24c30b338244566646729cfbaf58bfbb80e Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Sun, 4 Feb 2024 21:33:12 +0100
Subject: [PATCH 149/747] [Validator] Add additional versions (*_NO_PUBLIC,
 *_ONLY_PRIV & *_ONLY_RES) in IP address & CIDR constraint

---
 reference/constraints/Cidr.rst |  8 ++++----
 reference/constraints/Ip.rst   | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/reference/constraints/Cidr.rst b/reference/constraints/Cidr.rst
index d7bc9e6b4a0..24abeb57338 100644
--- a/reference/constraints/Cidr.rst
+++ b/reference/constraints/Cidr.rst
@@ -124,10 +124,10 @@ Parameter        Description
 **type**: ``string`` **default**: ``all``
 
 This determines exactly *how* the CIDR notation is validated and can take one
-of these values:
+of :ref:`IP version ranges <reference-constraint-ip-version>`.
 
-* ``4``: validates for CIDR notations that have an IPv4;
-* ``6``: validates for CIDR notations that have an IPv6;
-* ``all``: validates all CIDR formats.
+.. versionadded:: 7.1
+
+    The support of all IP version ranges was introduced in Symfony 7.1.
 
 .. _`CIDR`: https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
diff --git a/reference/constraints/Ip.rst b/reference/constraints/Ip.rst
index 2f05f677601..9168d463f77 100644
--- a/reference/constraints/Ip.rst
+++ b/reference/constraints/Ip.rst
@@ -97,6 +97,8 @@ Parameter        Description
 
 .. include:: /reference/constraints/_payload-option.rst.inc
 
+.. _reference-constraint-ip-version:
+
 ``version``
 ~~~~~~~~~~~
 
@@ -132,6 +134,33 @@ of a variety of different values:
 ``all_no_res``
     Validates for all IP formats but without reserved IP ranges
 
+**No public ranges**
+
+``4_no_public``
+    Validates for IPv4 but without public IP ranges
+``6_no_public``
+    Validates for IPv6 but without public IP ranges
+``all_no_public``
+    Validates for all IP formats but without public IP range
+
+**Only private ranges**
+
+``4_private``
+    Validates for IPv4 but without public and reserved ranges
+``6_private``
+    Validates for IPv6 but without public and reserved ranges
+``all_private``
+    Validates for all IP formats but without public and reserved ranges
+
+**Only reserved ranges**
+
+``4_reserved``
+    Validates for IPv4 but without private and public ranges
+``6_reserved``
+    Validates for IPv6 but without private and public ranges
+``all_reserved``
+    Validates for all IP formats but without private and public ranges
+
 **Only public ranges**
 
 ``4_public``
@@ -140,3 +169,8 @@ of a variety of different values:
     Validates for IPv6 but without private and reserved ranges
 ``all_public``
     Validates for all IP formats but without private and reserved ranges
+
+.. versionadded:: 7.1
+
+    The ``*_no_public``, ``*_reserved`` and ``*_public`` ranges were introduced
+    in Symfony 7.1.

From f332fd8d41065fabaac8c3d50349822f36f19b5a Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier@mbp.local>
Date: Mon, 5 Feb 2024 08:21:51 +0100
Subject: [PATCH 150/747] Fix a minor syntax issue

---
 components/serializer.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/components/serializer.rst b/components/serializer.rst
index 0dbd223877d..31c44216505 100644
--- a/components/serializer.rst
+++ b/components/serializer.rst
@@ -825,9 +825,9 @@ The Serializer component provides several built-in normalizers:
     To convert the objects to integers or floats, set the serializer context option
     ``DateTimeNormalizer::CAST_KEY`` to ``int`` or ``float``.
 
-.. versionadded:: 7.1
+    .. versionadded:: 7.1
 
-    ``DateTimeNormalizer::CAST_KEY`` context option was introduced in Symfony 7.1.
+        ``DateTimeNormalizer::CAST_KEY`` context option was introduced in Symfony 7.1.
 
 :class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeZoneNormalizer`
     This normalizer converts :phpclass:`DateTimeZone` objects into strings that

From 9388de664c185bec41a978ed1c18e4b71ac9cec9 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier@mbp.local>
Date: Mon, 5 Feb 2024 08:39:20 +0100
Subject: [PATCH 151/747] [ExpressionLanguage] Add more information about the
 min/max functions

---
 reference/formats/expression_language.rst | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/reference/formats/expression_language.rst b/reference/formats/expression_language.rst
index 9a3e78ef485..7daa4c98957 100644
--- a/reference/formats/expression_language.rst
+++ b/reference/formats/expression_language.rst
@@ -172,7 +172,10 @@ This will print out ``true``.
 ``min()`` function
 ~~~~~~~~~~~~~~~~~~
 
-This function will return the lowest value::
+This function will return the lowest value of the given parameters. You can pass
+different types of parameters (e.g. dates, strings, numeric values) and even mix
+them (e.g. pass numeric values and strings). Internally it uses the :phpfunction:`min`
+PHP function to find the lowest value::
 
     var_dump($expressionLanguage->evaluate(
         'min(1, 2, 3)'
@@ -183,7 +186,10 @@ This will print out ``1``.
 ``max()`` function
 ~~~~~~~~~~~~~~~~~~
 
-This function will return the highest value::
+This function will return the highest value of the given parameters. You can pass
+different types of parameters (e.g. dates, strings, numeric values) and even mix
+them (e.g. pass numeric values and strings). Internally it uses the :phpfunction:`max`
+PHP function to find the highest value::
 
     var_dump($expressionLanguage->evaluate(
         'max(1, 2, 3)'

From 015aed4d2bc7ba2bdc2a1be47cc51a6041e21f6f Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Mon, 5 Feb 2024 08:49:05 +0100
Subject: [PATCH 152/747] fix typo

---
 configuration/secrets.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configuration/secrets.rst b/configuration/secrets.rst
index 089f7da2892..f717456a22c 100644
--- a/configuration/secrets.rst
+++ b/configuration/secrets.rst
@@ -170,7 +170,7 @@ Reveal Existing Secrets
 -----------------------
 
 If you have the **decryption key**, the ``secrets:reveal`` command allows
-you to reveal a single secrets value.
+you to reveal a single secret's value.
 
 .. code-block:: terminal
 

From 17b273749d326ca45e385d296c036d4b402ab305 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Mon, 5 Feb 2024 08:50:11 +0100
Subject: [PATCH 153/747] fix typo

---
 components/serializer.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/serializer.rst b/components/serializer.rst
index 31c44216505..eab0e616c23 100644
--- a/components/serializer.rst
+++ b/components/serializer.rst
@@ -827,7 +827,7 @@ The Serializer component provides several built-in normalizers:
 
     .. versionadded:: 7.1
 
-        ``DateTimeNormalizer::CAST_KEY`` context option was introduced in Symfony 7.1.
+        The ``DateTimeNormalizer::CAST_KEY`` context option was introduced in Symfony 7.1.
 
 :class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeZoneNormalizer`
     This normalizer converts :phpclass:`DateTimeZone` objects into strings that

From f61c919fdf937f1827489a7c6d5e7fcac108db42 Mon Sep 17 00:00:00 2001
From: "hubert.lenoir" <hubert.lenoir@sensiolabs.com>
Date: Wed, 28 Dec 2022 13:39:22 +0100
Subject: [PATCH 154/747] [CssSelector] add support for :is() and :where()

---
 components/css_selector.rst | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/components/css_selector.rst b/components/css_selector.rst
index c09f80a3cf4..1331a11e616 100644
--- a/components/css_selector.rst
+++ b/components/css_selector.rst
@@ -92,7 +92,11 @@ Pseudo-classes are partially supported:
 * Not supported: ``*:first-of-type``, ``*:last-of-type``, ``*:nth-of-type`` and
   ``*:nth-last-of-type`` (all these work with an element name (e.g.
   ``li:first-of-type``) but not with the ``*`` selector).
-* Supported: ``*:only-of-type``, ``*:scope``.
+* Supported: ``*:only-of-type``, ``*:scope``, ``*:is`` and ``*:where``.
+
+.. versionadded:: 7.1
+
+    The support for ``*:is`` and ``*:where`` was introduced in Symfony 7.1.
 
 Learn more
 ----------

From 41bea4ef40b243db07c8d462e448fc9c679cf43e Mon Sep 17 00:00:00 2001
From: Maxime Doutreluingne <maxime.doutreluingne@gmail.com>
Date: Fri, 2 Feb 2024 19:09:24 +0100
Subject: [PATCH 155/747] Add message to #[MapEntity] for NotFoundHttpException

---
 doctrine.rst | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/doctrine.rst b/doctrine.rst
index e4be23664d3..01bd2e0aff7 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -820,6 +820,21 @@ control behavior:
 ``disabled``
     If true, the ``EntityValueResolver`` will not try to replace the argument.
 
+``message``
+    If a ``message`` option is configured, the value of the ``message`` option will be displayed in the development
+    environment for the :class:`Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException` exception::
+
+        #[Route('/product/{product_id}')]
+        public function show(
+            #[MapEntity(id: 'product_id', message: 'The product does not exist')]
+            Product $product
+        ): Response {
+        }
+
+.. versionadded:: 7.1
+
+    The ``message`` option was introduced in Symfony 7.1.
+
 Updating an Object
 ------------------
 

From 71c5335e821e028bd79448c342c0dc4a983a8486 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 5 Feb 2024 12:56:11 +0100
Subject: [PATCH 156/747] Minor tweaks

---
 doctrine.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doctrine.rst b/doctrine.rst
index 01bd2e0aff7..96239723d7e 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -821,8 +821,8 @@ control behavior:
     If true, the ``EntityValueResolver`` will not try to replace the argument.
 
 ``message``
-    If a ``message`` option is configured, the value of the ``message`` option will be displayed in the development
-    environment for the :class:`Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException` exception::
+    An optional custom message displayed when there's a :class:`Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException`,
+    but **only in the development environment** (you won't see this message in production)::
 
         #[Route('/product/{product_id}')]
         public function show(

From 9fddcaf033423b25ce7deb32768de0b9d87cdccc Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 5 Feb 2024 12:59:58 +0100
Subject: [PATCH 157/747] [HttpFoundation] Mention `HeaderRequestMatcher` and
 `QueryParameterRequestMatcher`

---
 components/http_foundation.rst | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/components/http_foundation.rst b/components/http_foundation.rst
index cd52464420f..4ecc36f4fba 100644
--- a/components/http_foundation.rst
+++ b/components/http_foundation.rst
@@ -388,17 +388,19 @@ address, it uses a certain HTTP method, etc.):
 
 * :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\AttributesRequestMatcher`
 * :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\ExpressionRequestMatcher`
+* :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\HeaderRequestMatcher`
 * :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\HostRequestMatcher`
 * :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\IpsRequestMatcher`
 * :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\IsJsonMatcher`
 * :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\MethodRequestMatcher`
 * :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\PathRequestMatcher`
 * :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\PortRequestMatcher`
+* :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\QueryParameterRequestMatcher`
+* :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\SchemeRequestMatcher`
 * :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\SchemeRequestMatcher`
 
 You can use them individually or combine them using the
-:class:`Symfony\\Component\\HttpFoundation\\ChainRequestMatcher`
-class::
+:class:`Symfony\\Component\\HttpFoundation\\ChainRequestMatcher` class::
 
     use Symfony\Component\HttpFoundation\ChainRequestMatcher;
     use Symfony\Component\HttpFoundation\RequestMatcher\HostRequestMatcher;
@@ -421,6 +423,11 @@ class::
         // ...
     }
 
+.. versionadded:: 7.1
+
+    The ``HeaderRequestMatcher`` and ``QueryParameterRequestMatcher`` were
+    introduced in Symfony 7.1.
+
 Accessing other Data
 ~~~~~~~~~~~~~~~~~~~~
 

From 4f75745ddfcba84bd3fbc7e41da181ca7950be5d Mon Sep 17 00:00:00 2001
From: Antoine Makdessi <amakdessi@me.com>
Date: Mon, 5 Feb 2024 08:35:06 +0100
Subject: [PATCH 158/747] Document `twig:lint` new option `excludes`

---
 templates.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/templates.rst b/templates.rst
index 7b6bb1ce68a..2abbf8053cc 100644
--- a/templates.rst
+++ b/templates.rst
@@ -818,6 +818,13 @@ errors. It's useful to run it before deploying your application to production
     # you can also show the deprecated features used in your templates
     $ php bin/console lint:twig --show-deprecations templates/email/
 
+    # you can also excludes directories
+    $ php bin/console lint:twig templates/ --excludes=data_collector --excludes=dev_tool
+
+.. versionadded:: 7.1
+
+    The option to exclude directories was introduced in Symfony 7.1.
+
 When running the linter inside `GitHub Actions`_, the output is automatically
 adapted to the format required by GitHub, but you can force that format too:
 

From 6144627161d4482330a5ccff46759d40325a8c86 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 5 Feb 2024 09:28:06 +0100
Subject: [PATCH 159/747] [Validator] Reword the list of options for the
 version option of the Ip constraint

---
 reference/constraints/Ip.rst | 80 +++++++-----------------------------
 1 file changed, 15 insertions(+), 65 deletions(-)

diff --git a/reference/constraints/Ip.rst b/reference/constraints/Ip.rst
index 9168d463f77..20cd4400c0a 100644
--- a/reference/constraints/Ip.rst
+++ b/reference/constraints/Ip.rst
@@ -104,71 +104,21 @@ Parameter        Description
 
 **type**: ``string`` **default**: ``4``
 
-This determines exactly *how* the IP address is validated and can take one
-of a variety of different values:
-
-**All ranges**
-
-``4``
-    Validates for IPv4 addresses
-``6``
-    Validates for IPv6 addresses
-``all``
-    Validates all IP formats
-
-**No private ranges**
-
-``4_no_priv``
-    Validates for IPv4 but without private IP ranges
-``6_no_priv``
-    Validates for IPv6 but without private IP ranges
-``all_no_priv``
-    Validates for all IP formats but without private IP ranges
-
-**No reserved ranges**
-
-``4_no_res``
-    Validates for IPv4 but without reserved IP ranges
-``6_no_res``
-    Validates for IPv6 but without reserved IP ranges
-``all_no_res``
-    Validates for all IP formats but without reserved IP ranges
-
-**No public ranges**
-
-``4_no_public``
-    Validates for IPv4 but without public IP ranges
-``6_no_public``
-    Validates for IPv6 but without public IP ranges
-``all_no_public``
-    Validates for all IP formats but without public IP range
-
-**Only private ranges**
-
-``4_private``
-    Validates for IPv4 but without public and reserved ranges
-``6_private``
-    Validates for IPv6 but without public and reserved ranges
-``all_private``
-    Validates for all IP formats but without public and reserved ranges
-
-**Only reserved ranges**
-
-``4_reserved``
-    Validates for IPv4 but without private and public ranges
-``6_reserved``
-    Validates for IPv6 but without private and public ranges
-``all_reserved``
-    Validates for all IP formats but without private and public ranges
-
-**Only public ranges**
-
-``4_public``
-    Validates for IPv4 but without private and reserved ranges
-``6_public``
-    Validates for IPv6 but without private and reserved ranges
-``all_public``
-    Validates for all IP formats but without private and reserved ranges
+This determines exactly *how* the IP address is validated. This option defines a
+lot of different possible values based on the ranges and the type of IP address
+that you want to allow/deny:
+
+====================  ===================  ===================  ==================
+Ranges Allowed        IPv4 addresses only  IPv6 addresses only  Both IPv4 and IPv6
+====================  ===================  ===================  ==================
+All                   ``4``                ``6``                ``all``
+All except private    ``4_no_priv``        ``6_no_priv``        ``all_no_priv``
+All except reserved   ``4_no_res``         ``6_no_res``         ``all_no_res``
+All except public     ``4_no_public``      ``6_no_public``      ``all_no_public``
+Only private          ``4_private``        ``6_private``        ``all_private``
+Only reserved         ``4_reserved``       ``6_reserved``       ``all_reserved``
+Only public           ``4_public``         ``6_public``         ``all_public``
+====================  ===================  ===================  ==================
 
 .. versionadded:: 7.1
 

From aefde3c393007dfc4c903f6efc0806cefad093ba Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Mon, 5 Feb 2024 20:49:39 +0100
Subject: [PATCH 160/747] Remove SchemeRequestMatcher duplication

---
 components/http_foundation.rst | 1 -
 1 file changed, 1 deletion(-)

diff --git a/components/http_foundation.rst b/components/http_foundation.rst
index ee88fb14595..06d59f78cae 100644
--- a/components/http_foundation.rst
+++ b/components/http_foundation.rst
@@ -397,7 +397,6 @@ address, it uses a certain HTTP method, etc.):
 * :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\PortRequestMatcher`
 * :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\QueryParameterRequestMatcher`
 * :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\SchemeRequestMatcher`
-* :class:`Symfony\\Component\\HttpFoundation\\RequestMatcher\\SchemeRequestMatcher`
 
 You can use them individually or combine them using the
 :class:`Symfony\\Component\\HttpFoundation\\ChainRequestMatcher` class::

From 0e03673ac31503aced6df4e42d6f45b4807133d8 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 6 Feb 2024 10:27:22 +0100
Subject: [PATCH 161/747] [HttpFoundation] Add support for `\SplTempFileObject`
 in `BinaryFileResponse`

---
 components/http_foundation.rst | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/components/http_foundation.rst b/components/http_foundation.rst
index 06d59f78cae..b08aeb8380b 100644
--- a/components/http_foundation.rst
+++ b/components/http_foundation.rst
@@ -841,6 +841,23 @@ It is possible to delete the file after the response is sent with the
 :method:`Symfony\\Component\\HttpFoundation\\BinaryFileResponse::deleteFileAfterSend` method.
 Please note that this will not work when the ``X-Sendfile`` header is set.
 
+Alternatively, ``BinaryFileResponse`` supports instances of ``\SplTempFileObject``.
+This is useful when you want to serve a file that has been created in memory
+and that will be automatically deleted after the response is sent::
+
+    use Symfony\Component\HttpFoundation\BinaryFileResponse;
+
+    $file = new \SplTempFileObject();
+    $file->fwrite('Hello World');
+    $file->rewind();
+
+    $response = new BinaryFileResponse($file);
+
+.. versionadded:: 7.1
+
+    The support for ``\SplTempFileObject`` in ``BinaryFileResponse``
+    was introduced in Symfony 7.1.
+
 If the size of the served file is unknown (e.g. because it's being generated on the fly,
 or because a PHP stream filter is registered on it, etc.), you can pass a ``Stream``
 instance to ``BinaryFileResponse``. This will disable ``Range`` and ``Content-Length``

From 4085aeddc191f7823ae0dc093310028259e54a65 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 7 Feb 2024 13:26:03 +0100
Subject: [PATCH 162/747] [Serializer] Add Default and "class name" default
 groups

---
 serializer.rst | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/serializer.rst b/serializer.rst
index e3480c0b035..701e5918848 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -383,6 +383,18 @@ stored in one of the following locations:
 * All ``*.yaml`` and ``*.xml`` files in the ``Resources/config/serialization/``
   directory of a bundle.
 
+.. note::
+
+    By default, the ``Default`` group is used when normalizing and denormalizing
+    objects. A group corresponding to the class name is also used. For example,
+    if you are normalizing a ``App\Entity\Product`` object, the ``Product`` group
+    is also included by default.
+
+    .. versionadded:: 7.1
+
+        The default use of the class name and ``Default`` groups when normalizing
+        and denormalizing objects was introduced in Symfony 7.1.
+
 .. _serializer-enabling-metadata-cache:
 
 Using Nested Attributes

From 5d2b2a6fd738c48de9275535cf1522e972c5d5f4 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 7 Feb 2024 13:32:43 +0100
Subject: [PATCH 163/747] [Yaml] Allow to get all the enum cases

---
 components/yaml.rst        | 20 ++++++++++++++++++++
 reference/formats/yaml.rst | 13 +++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/components/yaml.rst b/components/yaml.rst
index 627fc4479e0..5f724e0572c 100644
--- a/components/yaml.rst
+++ b/components/yaml.rst
@@ -355,6 +355,26 @@ and the special ``!php/enum`` syntax to parse them as proper PHP enums::
     // the value of the 'foo' key is a string because it missed the `!php/enum` syntax
     // $parameters = ['foo' => 'FooEnum::Foo', 'bar' => 'foo'];
 
+You can also use ``!php/enum`` to get all the enumeration cases by only
+giving the enumeration FQCN::
+
+    enum FooEnum: string
+    {
+        case Foo = 'foo';
+        case Bar = 'bar';
+    }
+
+    // ...
+
+    $yaml = '{ bar: !php/enum FooEnum }';
+    $parameters = Yaml::parse($yaml, Yaml::PARSE_CONSTANT);
+    // $parameters = ['bar' => ['foo', 'bar']];
+
+.. versionadded:: 7.1
+
+    The support for using the enum FQCN without specifying a case
+    was introduced in Symfony 7.1.
+
 Parsing and Dumping of Binary Data
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/reference/formats/yaml.rst b/reference/formats/yaml.rst
index 64adac599fb..6a61cafa74a 100644
--- a/reference/formats/yaml.rst
+++ b/reference/formats/yaml.rst
@@ -346,6 +346,19 @@ official YAML specification but are useful in Symfony applications:
           # ... or you can also use "->value" to directly use the value of a BackedEnum case
           operator_type: !php/enum App\Operator\Enum\Type::Or->value
 
+  This tag allows to omit the enum case and only provide the enum FQCN
+  to return an array of all available enum cases:
+
+  .. code-block:: yaml
+
+      data:
+          operator_types: !php/enum App\Operator\Enum\Type
+
+  .. versionadded:: 7.1
+
+    The support for using the enum FQCN without specifying a case
+    was introduced in Symfony 7.1.
+
 Unsupported YAML Features
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 

From a3ba7fcc34f3cdcbc7880a99dc91b47a319661dd Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 7 Feb 2024 14:01:49 +0100
Subject: [PATCH 164/747] [ExpressionLanguage] Add flags support in `parse()`
 and `lint()`

---
 components/expression_language.rst | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/components/expression_language.rst b/components/expression_language.rst
index d335710923e..038251066e1 100644
--- a/components/expression_language.rst
+++ b/components/expression_language.rst
@@ -112,6 +112,30 @@ other hand, returns a boolean indicating if the expression is valid or not::
 
     var_dump($expressionLanguage->lint('1 + 2')); // displays true
 
+The call to these methods can be configured through flags. The available flags
+are available in the :class:`Symfony\\Component\\ExpressionLanguage\\Parser` class
+and are the following:
+
+* ``IGNORE_UNKNOWN_VARIABLES``: don't throw an exception if a variable is not
+  defined in the expression;
+* ``IGNORE_UNKNOWN_FUNCTIONS``: don't throw an exception if a function is not
+  defined in the expression.
+
+This is how you can use these flags::
+
+    use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
+    use Symfony\Component\ExpressionLanguage\Parser;
+
+    $expressionLanguage = new ExpressionLanguage();
+
+    // this return true because the unknown variables and functions are ignored
+    var_dump($expressionLanguage->lint('unknown_var + unknown_function()', Parser::IGNORE_UNKNOWN_VARIABLES | Parser::IGNORE_UNKNOWN_FUNCTIONS));
+
+.. versionadded:: 7.1
+
+    The support for flags in the ``parse()`` and ``lint()`` methods
+    was introduced in Symfony 7.1.
+
 Passing in Variables
 --------------------
 

From add92fa186a6e9d824f28bd1110d19674e20ca8b Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 7 Feb 2024 15:52:31 +0100
Subject: [PATCH 165/747] Minor tweak

---
 components/expression_language.rst | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/components/expression_language.rst b/components/expression_language.rst
index d43b9df0f6f..fa07903bbb7 100644
--- a/components/expression_language.rst
+++ b/components/expression_language.rst
@@ -110,9 +110,8 @@ other hand, returns a boolean indicating if the expression is valid or not::
 
     var_dump($expressionLanguage->lint('1 + 2')); // displays true
 
-The call to these methods can be configured through flags. The available flags
-are available in the :class:`Symfony\\Component\\ExpressionLanguage\\Parser` class
-and are the following:
+The behavior of these methods can be configured with some flags defined in the
+:class:`Symfony\\Component\\ExpressionLanguage\\Parser` class:
 
 * ``IGNORE_UNKNOWN_VARIABLES``: don't throw an exception if a variable is not
   defined in the expression;
@@ -126,7 +125,7 @@ This is how you can use these flags::
 
     $expressionLanguage = new ExpressionLanguage();
 
-    // this return true because the unknown variables and functions are ignored
+    // this returns true because the unknown variables and functions are ignored
     var_dump($expressionLanguage->lint('unknown_var + unknown_function()', Parser::IGNORE_UNKNOWN_VARIABLES | Parser::IGNORE_UNKNOWN_FUNCTIONS));
 
 .. versionadded:: 7.1

From 28254a6b33eaa2cee81eb5e46cb68d2a05a4f7d4 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 7 Feb 2024 16:41:34 +0100
Subject: [PATCH 166/747] Minor reword

---
 serializer.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/serializer.rst b/serializer.rst
index 701e5918848..6f75d65afc4 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -385,10 +385,10 @@ stored in one of the following locations:
 
 .. note::
 
-    By default, the ``Default`` group is used when normalizing and denormalizing
-    objects. A group corresponding to the class name is also used. For example,
-    if you are normalizing a ``App\Entity\Product`` object, the ``Product`` group
-    is also included by default.
+    The groups used by default when normalizing and denormalizing objects are
+    ``Default`` and the group that matches the class name. For example, if you
+    are normalizing a ``App\Entity\Product`` object, the groups used are
+    ``Default`` and ``Product``.
 
     .. versionadded:: 7.1
 

From 56c8b4d41f09af3d32730bdbda4ac0f2944e860a Mon Sep 17 00:00:00 2001
From: Mathias Arlaud <mathias.arlaud@gmail.com>
Date: Thu, 8 Feb 2024 10:14:03 +0100
Subject: [PATCH 167/747] [Serializer] Fix recursive custom normalizer

---
 serializer/custom_normalizer.rst | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/serializer/custom_normalizer.rst b/serializer/custom_normalizer.rst
index 447076fff46..636ba70fd37 100644
--- a/serializer/custom_normalizer.rst
+++ b/serializer/custom_normalizer.rst
@@ -12,8 +12,8 @@ Creating a New Normalizer
 Imagine you want add, modify, or remove some properties during the serialization
 process. For that you'll have to create your own normalizer. But it's usually
 preferable to let Symfony normalize the object, then hook into the normalization
-to customize the normalized data. To do that, leverage the
-``NormalizerAwareInterface`` and the ``NormalizerAwareTrait``. This will give
+to customize the normalized data. To do that, you can inject a
+``NormalizerInterface`` and wire it to Symfony's object normalizer. This will give
 you access to a ``$normalizer`` property which takes care of most of the
 normalization process::
 
@@ -21,16 +21,16 @@ normalization process::
     namespace App\Serializer;
 
     use App\Entity\Topic;
+    use Symfony\Component\DependencyInjection\Attribute\Autowire;
     use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
-    use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
-    use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
     use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
 
-    class TopicNormalizer implements NormalizerInterface, NormalizerAwareInterface
+    class TopicNormalizer implements NormalizerInterface
     {
-        use NormalizerAwareTrait;
-
         public function __construct(
+            #[Autowire(service: 'serializer.normalizer.object')]
+            private readonly NormalizerInterface $normalizer,
+
             private UrlGeneratorInterface $router,
         ) {
         }

From ebd373cafcd0cfe49cc8bbde7ba64b567722e4ac Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Thu, 8 Feb 2024 17:54:25 +0100
Subject: [PATCH 168/747] Fix broken class links

---
 bundles/prepend_extension.rst                      | 4 ++--
 service_container/service_subscribers_locators.rst | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/bundles/prepend_extension.rst b/bundles/prepend_extension.rst
index 4bd1c7c6a67..613cda7489f 100644
--- a/bundles/prepend_extension.rst
+++ b/bundles/prepend_extension.rst
@@ -187,7 +187,7 @@ method::
     The ``prependExtension()`` method, like ``prepend()``, is called only at compile time.
 
 Alternatively, you can use the ``prepend`` parameter of the
-:method:`Symfony\\Component\\DependencyInjection\\Loader\\ContainerConfigurator::extension`
+:method:`Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator::extension`
 method::
 
     use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -211,7 +211,7 @@ method::
 .. versionadded:: 7.1
 
     The ``prepend`` parameter of the
-    :method:`Symfony\\Component\\DependencyInjection\\Loader\\ContainerConfigurator::extension`
+    :method:`Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator::extension`
     method was added in Symfony 7.1.
 
 More than one Bundle using PrependExtensionInterface
diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst
index 31a9fa55f3b..21a7ab295d2 100644
--- a/service_container/service_subscribers_locators.rst
+++ b/service_container/service_subscribers_locators.rst
@@ -123,7 +123,7 @@ In this example, the ``$handler`` service is only instantiated when the
 
 You can also type-hint the service locator argument with
 :class:`Symfony\\Contracts\\Service\\ServiceCollectionInterface` instead of
-:class:`Psr\\Container\\ContainerInterface`. By doing so, you'll be able to
+``Psr\Container\ContainerInterface``. By doing so, you'll be able to
 count and iterate over the services of the locator::
 
     // ...

From c881eab2864a24d9ec567d06630eeaa2d6331373 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Thu, 8 Feb 2024 19:55:50 +0100
Subject: [PATCH 169/747] [Security] add CAS 2.0 AccessToken handler

---
 security/access_token.rst | 188 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 185 insertions(+), 3 deletions(-)

diff --git a/security/access_token.rst b/security/access_token.rst
index 29fbfbc8bb6..83e33bae901 100644
--- a/security/access_token.rst
+++ b/security/access_token.rst
@@ -697,6 +697,187 @@ create your own User from the claims, you must
         }
     }
 
+Using CAS 2.0
+-------------
+
+`Central Authentication Service (CAS)`_ is an enterprise multilingual single
+sign-on solution and identity provider for the web and attempts to be a
+comprehensive platform for your authentication and authorization needs.
+
+Configure the Cas2Handler
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Symfony provides a generic ``Cas2Handler`` to call your CAS server. It requires
+the ``symfony/http-client`` package to make the needed HTTP requests. If you
+haven't installed it yet, run this command:
+
+.. code-block:: terminal
+
+    $ composer require symfony/http-client
+
+You can configure a ``cas`` ``token_handler``:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/security.yaml
+        security:
+            firewalls:
+                main:
+                    access_token:
+                        token_handler:
+                            cas:
+                                validation_url: https://www.example.com/cas/validate
+
+    .. code-block:: xml
+
+        <!-- config/packages/security.xml -->
+        <?xml version="1.0" encoding="UTF-8"?>
+        <srv:container xmlns="http://symfony.com/schema/dic/security"
+            xmlns:srv="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                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">
+
+            <config>
+                <firewall name="main">
+                    <access-token>
+                        <token-handler>
+                            <cas validation-url="https://www.example.com/cas/validate"/>
+                        </token-handler>
+                    </access-token>
+                </firewall>
+            </config>
+        </srv:container>
+
+    .. code-block:: php
+
+        // config/packages/security.php
+        use Symfony\Config\SecurityConfig;
+
+        return static function (SecurityConfig $security) {
+            $security->firewall('main')
+                ->accessToken()
+                    ->tokenHandler()
+                        ->cas()
+                            ->validationUrl('https://www.example.com/cas/validate')
+            ;
+        };
+
+The ``cas`` token handler automatically creates an HTTP client to call
+the specified ``validation_url``. If you prefer using your own client, you can
+specify the service name via the ``http_client`` option:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/security.yaml
+        security:
+            firewalls:
+                main:
+                    access_token:
+                        token_handler:
+                            cas:
+                                validation_url: https://www.example.com/cas/validate
+                                http_client: cas.client
+
+    .. code-block:: xml
+
+        <!-- config/packages/security.xml -->
+        <?xml version="1.0" encoding="UTF-8"?>
+        <srv:container xmlns="http://symfony.com/schema/dic/security"
+            xmlns:srv="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                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">
+
+            <config>
+                <firewall name="main">
+                    <access-token>
+                        <token-handler>
+                            <cas validation-url="https://www.example.com/cas/validate" http-client="cas.client"/>
+                        </token-handler>
+                    </access-token>
+                </firewall>
+            </config>
+        </srv:container>
+
+    .. code-block:: php
+
+        // config/packages/security.php
+        use Symfony\Config\SecurityConfig;
+
+        return static function (SecurityConfig $security) {
+            $security->firewall('main')
+                ->accessToken()
+                    ->tokenHandler()
+                        ->cas()
+                            ->validationUrl('https://www.example.com/cas/validate')
+                            ->httpClient('cas.client')
+            ;
+        };
+
+By default the token handler will read the validation URL XML response with
+ ``cas`` prefix but you can configure another prefix:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/security.yaml
+        security:
+            firewalls:
+                main:
+                    access_token:
+                        token_handler:
+                            cas:
+                                validation_url: https://www.example.com/cas/validate
+                                prefix: cas-example
+
+    .. code-block:: xml
+
+        <!-- config/packages/security.xml -->
+        <?xml version="1.0" encoding="UTF-8"?>
+        <srv:container xmlns="http://symfony.com/schema/dic/security"
+            xmlns:srv="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                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">
+
+            <config>
+                <firewall name="main">
+                    <access-token>
+                        <token-handler>
+                            <cas validation-url="https://www.example.com/cas/validate" prefix="cas-example"/>
+                        </token-handler>
+                    </access-token>
+                </firewall>
+            </config>
+        </srv:container>
+
+    .. code-block:: php
+
+        // config/packages/security.php
+        use Symfony\Config\SecurityConfig;
+
+        return static function (SecurityConfig $security) {
+            $security->firewall('main')
+                ->accessToken()
+                    ->tokenHandler()
+                        ->cas()
+                            ->validationUrl('https://www.example.com/cas/validate')
+                            ->prefix('cas-example')
+            ;
+        };
+
 Creating Users from Token
 -------------------------
 
@@ -727,8 +908,9 @@ need a user provider to create a user from the database::
 When using this strategy, you can omit the ``user_provider`` configuration
 for :ref:`stateless firewalls <reference-security-stateless>`.
 
+.. _`Central Authentication Service (CAS)`: https://en.wikipedia.org/wiki/Central_Authentication_Service
 .. _`JSON Web Tokens (JWT)`: https://datatracker.ietf.org/doc/html/rfc7519
-.. _`SAML2 (XML structures)`: https://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html
-.. _`RFC6750`: https://datatracker.ietf.org/doc/html/rfc6750
-.. _`OpenID Connect Specification`: https://openid.net/specs/openid-connect-core-1_0.html
 .. _`OpenID Connect (OIDC)`: https://en.wikipedia.org/wiki/OpenID#OpenID_Connect_(OIDC)
+.. _`OpenID Connect Specification`: https://openid.net/specs/openid-connect-core-1_0.html
+.. _`RFC6750`: https://datatracker.ietf.org/doc/html/rfc6750
+.. _`SAML2 (XML structures)`: https://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html

From 998929c21bbbaf9de1e3aa65d43309c951bf767b Mon Sep 17 00:00:00 2001
From: William Pinaud <thedocrepinsfx@gmail.com>
Date: Wed, 31 Jan 2024 12:36:17 +0100
Subject: [PATCH 170/747] Update form.rst for flattened form errors

Updated to reflect the code.
---
 components/form.rst | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/components/form.rst b/components/form.rst
index 42a5a00bbae..7584d223032 100644
--- a/components/form.rst
+++ b/components/form.rst
@@ -749,10 +749,11 @@ method to access the list of errors. It returns a
     // "firstName" field
     $errors = $form['firstName']->getErrors();
 
-    // a FormErrorIterator instance in a flattened structure
+    // a FormErrorIterator instance including child forms in a flattened structure
+    // use getOrigin() to determine the form causing the error
     $errors = $form->getErrors(true);
 
-    // a FormErrorIterator instance representing the form tree structure
+    // a FormErrorIterator instance including child forms without flattening the output structure
     $errors = $form->getErrors(true, false);
 
 Clearing Form Errors

From 91d8296e948cce1ce4a11cb2d63cf31a1750fba4 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Fri, 9 Feb 2024 19:31:40 +0100
Subject: [PATCH 171/747] [Config] Allow custom meta location in ConfigCache

---
 components/config/caching.rst | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/components/config/caching.rst b/components/config/caching.rst
index 810db48107e..18620c0d8cf 100644
--- a/components/config/caching.rst
+++ b/components/config/caching.rst
@@ -55,3 +55,17 @@ the cache file itself. This ``.meta`` file contains the serialized resources,
 whose timestamps are used to determine if the cache is still fresh. When
 not in debug mode, the cache is considered to be "fresh" as soon as it exists,
 and therefore no ``.meta`` file will be generated.
+
+You can explicitly define the absolute path to the meta file::
+
+    use Symfony\Component\Config\ConfigCache;
+    use Symfony\Component\Config\Resource\FileResource;
+
+    $cachePath = __DIR__.'/cache/appUserMatcher.php';
+
+    // the third optional argument indicates the absolute path to the meta file
+    $userMatcherCache = new ConfigCache($cachePath, true, '/my/absolute/path/to/cache.meta');
+
+.. versionadded:: 7.1
+
+    The argument to customize the meta file path was introduced in Symfony 7.1.

From f4d9b2c595d23b936541770c471d3631881f740e Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Mon, 12 Feb 2024 19:13:01 +0100
Subject: [PATCH 172/747] Minor: remove duplicated lines

---
 components/dependency_injection.rst     |  1 -
 migration.rst                           |  1 -
 reference/configuration/framework.rst   | 26 -------------------------
 reference/configuration/security.rst    |  1 -
 reference/constraints/Unique.rst        |  1 -
 workflow/workflow-and-state-machine.rst |  1 -
 6 files changed, 31 deletions(-)

diff --git a/components/dependency_injection.rst b/components/dependency_injection.rst
index 79b35bf312e..93e8af711cf 100644
--- a/components/dependency_injection.rst
+++ b/components/dependency_injection.rst
@@ -178,7 +178,6 @@ You can override this behavior as follows::
     // the second argument is optional and defines what to do when the service doesn't exist
     $newsletterManager = $containerBuilder->get('newsletter_manager', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE);
 
-
 These are all the possible behaviors:
 
  * ``ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE``: throws an exception
diff --git a/migration.rst b/migration.rst
index 16fa43fa281..44485248545 100644
--- a/migration.rst
+++ b/migration.rst
@@ -340,7 +340,6 @@ somewhat like this::
             throw new \Exception("Unhandled legacy mapping for $requestPathInfo");
         }
 
-
         public static function handleRequest(Request $request, Response $response, string $publicDirectory): void
         {
             $legacyScriptFilename = LegacyBridge::getLegacyScript($request);
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 2491b94de5f..23975913173 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -2847,32 +2847,6 @@ annotation changes). For performance reasons, it is recommended to disable
 debug mode in production, which will happen automatically if you use the
 default value.
 
-secrets
-~~~~~~~
-
-decryption_env_var
-..................
-
-**type**: ``string`` **default**: ``base64:default::SYMFONY_DECRYPTION_SECRET``
-
-The environment variable that contains the decryption key.
-
-local_dotenv_file
-.................
-
-**type**: ``string`` **default**: ``%kernel.project_dir%/.env.%kernel.environment%.local``
-
-Path to an dotenv file that holds secrets. This is primarily used for testing.
-
-vault_directory
-...............
-
-**type**: ``string`` **default**: ``%kernel.project_dir%/config/secrets/%kernel.environment%``
-
-The directory where the vault of secrets is stored.
-
-.. _configuration-framework-serializer:
-
 serializer
 ~~~~~~~~~~
 
diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst
index 64a16c7d616..590f2472425 100644
--- a/reference/configuration/security.rst
+++ b/reference/configuration/security.rst
@@ -495,7 +495,6 @@ user logs out::
                         ->domain('example.com');
         };
 
-
 clear_site_data
 ...............
 
diff --git a/reference/constraints/Unique.rst b/reference/constraints/Unique.rst
index c7ee71329c4..8954f455086 100644
--- a/reference/constraints/Unique.rst
+++ b/reference/constraints/Unique.rst
@@ -95,7 +95,6 @@ Options
 
 **type**: ``array`` | ``string``
 
-
 This is defines the key or keys in a collection that should be checked for
 uniqueness. By default, all collection keys are checked for uniqueness.
 
diff --git a/workflow/workflow-and-state-machine.rst b/workflow/workflow-and-state-machine.rst
index e72b50f8d1e..c94214fc22f 100644
--- a/workflow/workflow-and-state-machine.rst
+++ b/workflow/workflow-and-state-machine.rst
@@ -282,7 +282,6 @@ machine type, use ``camelCased workflow name + StateMachine``::
         // ...
     }
 
-
 Automatic and Manual Validation
 -------------------------------
 

From 77c49b3fef00aa7b9f5df6d2ec88b4faaf6a38ed Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 13 Feb 2024 11:44:48 +0100
Subject: [PATCH 173/747] [Workflow] Support omitting `places` option

---
 workflow.rst                            | 17 ++++++++++++++++-
 workflow/workflow-and-state-machine.rst | 11 +++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/workflow.rst b/workflow.rst
index 99d23cdcfae..7e45c7693c1 100644
--- a/workflow.rst
+++ b/workflow.rst
@@ -60,7 +60,7 @@ follows:
                     supports:
                         - App\Entity\BlogPost
                     initial_marking: draft
-                    places:
+                    places:          # defining places manually is optional
                         - draft
                         - reviewed
                         - rejected
@@ -97,10 +97,13 @@ follows:
                     </framework:marking-store>
                     <framework:support>App\Entity\BlogPost</framework:support>
                     <framework:initial-marking>draft</framework:initial-marking>
+
+                    <!-- defining places manually is optional -->
                     <framework:place>draft</framework:place>
                     <framework:place>reviewed</framework:place>
                     <framework:place>rejected</framework:place>
                     <framework:place>published</framework:place>
+
                     <framework:transition name="to_review">
                         <framework:from>draft</framework:from>
                         <framework:to>reviewed</framework:to>
@@ -135,6 +138,7 @@ follows:
                 ->type('method')
                 ->property('currentPlace');
 
+            // defining places manually is optional
             $blogPublishing->place()->name('draft');
             $blogPublishing->place()->name('reviewed');
             $blogPublishing->place()->name('rejected');
@@ -168,6 +172,17 @@ follows:
     ``'draft'`` or ``!php/const App\Entity\BlogPost::TRANSITION_TO_REVIEW``
     instead of ``'to_review'``.
 
+.. tip::
+
+    You can omit the ``places`` option if your transitions define all the places
+    that are used in the workflow. Symfony will automatically extract the places
+    from the transitions.
+
+    .. versionadded:: 7.1
+
+        The support for omitting the ``places`` option was introduced in
+        Symfony 7.1.
+
 The configured property will be used via its implemented getter/setter methods by the marking store::
 
     // src/Entity/BlogPost.php
diff --git a/workflow/workflow-and-state-machine.rst b/workflow/workflow-and-state-machine.rst
index e72b50f8d1e..04abf590f2f 100644
--- a/workflow/workflow-and-state-machine.rst
+++ b/workflow/workflow-and-state-machine.rst
@@ -252,6 +252,17 @@ Below is the configuration for the pull request state machine.
                     ->to(['review']);
         };
 
+.. tip::
+
+    You can omit the ``places`` option if your transitions define all the places
+    that are used in the workflow. Symfony will automatically extract the places
+    from the transitions.
+
+    .. versionadded:: 7.1
+
+        The support for omitting the ``places`` option was introduced in
+        Symfony 7.1.
+
 Symfony automatically creates a service for each workflow (:class:`Symfony\\Component\\Workflow\\Workflow`)
 or state machine (:class:`Symfony\\Component\\Workflow\\StateMachine`) you
 have defined in your configuration. You can use the workflow inside a class by using

From e1203e74eebfad066a7acef86781608999d0e9e5 Mon Sep 17 00:00:00 2001
From: Joseph Bielawski <stloyd@users.noreply.github.com>
Date: Wed, 14 Feb 2024 10:29:01 +0100
Subject: [PATCH 174/747] [Notifier] Add Pushy docs

---
 notifier.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/notifier.rst b/notifier.rst
index 774294c3577..4e16edaf039 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -453,11 +453,16 @@ Service          Package                               DSN
 `OneSignal`_     ``symfony/one-signal-notifier``       ``onesignal://APP_ID:API_KEY@default?defaultRecipientId=DEFAULT_RECIPIENT_ID``
 `PagerDuty`_     ``symfony/pager-duty-notifier``       ``pagerduty://TOKEN@SUBDOMAIN``
 `Pushover`_      ``symfony/pushover-notifier``         ``pushover://USER_KEY:APP_TOKEN@default``
+`Pushy`_         ``symfony/pushy-notifier``            ``pushy://API_KEY@default``
 ===============  ====================================  ==============================================================================
 
 To enable a texter, add the correct DSN in your ``.env`` file and
 configure the ``texter_transports``:
 
+.. versionadded:: 7.1
+
+    The `Pushy`_ integration was introduced in Symfony 7.1.
+
 .. code-block:: bash
 
     # .env
@@ -1019,6 +1024,7 @@ is dispatched. Listeners receive a
 .. _`PagerDuty`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/PagerDuty/README.md
 .. _`Plivo`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Plivo/README.md
 .. _`Pushover`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Pushover/README.md
+.. _`Pushy`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Pushy/README.md
 .. _`Redlink`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Redlink/README.md
 .. _`RFC 3986`: https://www.ietf.org/rfc/rfc3986.txt
 .. _`RingCentral`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/RingCentral/README.md

From f3d9113d5a5d988144cc2b57d8a2b05cb4c01aad Mon Sep 17 00:00:00 2001
From: Xbird <contact@xbird.me>
Date: Wed, 21 Feb 2024 21:59:16 +0100
Subject: [PATCH 175/747] Replace old docker compose filename

docker-compose.yml/yaml to compose.yaml
---
 .doctor-rst.yaml         |  1 +
 setup/docker.rst         |  2 +-
 setup/symfony_server.rst | 12 ++++++------
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/.doctor-rst.yaml b/.doctor-rst.yaml
index ac51116da5b..f4c48a0bf54 100644
--- a/.doctor-rst.yaml
+++ b/.doctor-rst.yaml
@@ -93,6 +93,7 @@ whitelist:
         - '/``.yml``/'
         - '/(.*)\.orm\.yml/' # currently DoctrineBundle only supports .yml
         - /docker-compose\.yml/
+        - /compose\.yaml/
     lines:
         - 'in config files, so the old ``app/config/config_dev.yml`` goes to'
         - '#. The most important config file is ``app/config/services.yml``, which now is'
diff --git a/setup/docker.rst b/setup/docker.rst
index 63da416e7bf..c00192e08d4 100644
--- a/setup/docker.rst
+++ b/setup/docker.rst
@@ -19,7 +19,7 @@ Flex Recipes & Docker Configuration
 
 The :ref:`Flex recipe <symfony-flex>` for some packages also include Docker configuration.
 For example, when you run ``composer require doctrine`` (to get ``symfony/orm-pack``),
-your ``docker-compose.yml`` file will automatically be updated to include a
+your ``compose.yaml`` file will automatically be updated to include a
 ``database`` service.
 
 The first time you install a recipe containing Docker config, Flex will ask you
diff --git a/setup/symfony_server.rst b/setup/symfony_server.rst
index c6b817ebdb5..6c666a7ad2e 100644
--- a/setup/symfony_server.rst
+++ b/setup/symfony_server.rst
@@ -388,7 +388,7 @@ Consider the following configuration:
 
 .. code-block:: yaml
 
-    # docker-compose.yaml
+    # compose.yaml
     services:
         database:
             ports: [3306]
@@ -401,12 +401,12 @@ variables accordingly with the service name (``database``) as a prefix:
 If the service is not in the supported list below, generic environment
 variables are set: ``PORT``, ``IP``, and ``HOST``.
 
-If the ``docker-compose.yaml`` names do not match Symfony's conventions, add a
+If the ``compose.yaml`` names do not match Symfony's conventions, add a
 label to override the environment variables prefix:
 
 .. code-block:: yaml
 
-    # docker-compose.yaml
+    # compose.yaml
     services:
         db:
             ports: [3306]
@@ -471,7 +471,7 @@ check the "Symfony Server" section in the web debug toolbar; you'll see that
 
     .. code-block:: yaml
 
-        # docker-compose.yaml
+        # compose.yaml
         services:
             db:
                 ports: [3306]
@@ -485,10 +485,10 @@ its location, same as for ``docker-compose``:
 .. code-block:: bash
 
     # start your containers:
-    COMPOSE_FILE=docker/docker-compose.yaml COMPOSE_PROJECT_NAME=project_name docker-compose up -d
+    COMPOSE_FILE=docker/compose.yaml COMPOSE_PROJECT_NAME=project_name docker-compose up -d
 
     # run any Symfony CLI command:
-    COMPOSE_FILE=docker/docker-compose.yaml COMPOSE_PROJECT_NAME=project_name symfony var:export
+    COMPOSE_FILE=docker/compose.yaml COMPOSE_PROJECT_NAME=project_name symfony var:export
 
 .. note::
 

From 4fc32cdad4d9a6a1373ca267e0066b774316f2e4 Mon Sep 17 00:00:00 2001
From: Valentin-Nicusor Barbu <jimiero@gmail.com>
Date: Thu, 8 Feb 2024 13:50:42 +0200
Subject: [PATCH 176/747] [Notifier] [SMSense] add docs

---
 notifier.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/notifier.rst b/notifier.rst
index 774294c3577..3cf7f19d3df 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -96,6 +96,7 @@ Service             Package                                DSN
 `Smsapi`_           ``symfony/smsapi-notifier``            ``smsapi://TOKEN@default?from=FROM``
 `Smsbox`_           ``symfony/smsbox-notifier``            ``smsbox://APIKEY@default?mode=MODE&strategy=STRATEGY&sender=SENDER``
 `Smsc`_             ``symfony/smsc-notifier``              ``smsc://LOGIN:PASSWORD@default?from=FROM``
+`SMSense`_          ``symfony/smsense-notifier``           ``smsense://API_TOKEN@default?from=FROM``
 `SpotHit`_          ``symfony/spot-hit-notifier``          ``spothit://TOKEN@default?from=FROM``
 `Telnyx`_           ``symfony/telnyx-notifier``            ``telnyx://API_KEY@default?from=FROM&messaging_profile_id=MESSAGING_PROFILE_ID``
 `TurboSms`_         ``symfony/turbo-sms-notifier``         ``turbosms://AUTH_TOKEN@default?from=FROM``
@@ -114,7 +115,7 @@ Service             Package                                DSN
 
 .. versionadded:: 7.1
 
-    The `SmsSluzba`_ integration was introduced in Symfony 7.1.
+    The `SmsSluzba`_ and  `SMSense`_ integrations were introduced in Symfony 7.1.
 
 .. deprecated:: 7.1
 

From 7c5c13f00a06be24f903c21bc422a037e4012097 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Fri, 23 Feb 2024 08:46:30 +0100
Subject: [PATCH 177/747] -

---
 notifier.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/notifier.rst b/notifier.rst
index 1241298d3ee..be51386544a 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -1041,6 +1041,7 @@ is dispatched. Listeners receive a
 .. _`Smsbox`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Smsbox/README.md
 .. _`Smsapi`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Smsapi/README.md
 .. _`Smsc`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Smsc/README.md
+.. _`SMSense`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SMSense/README.md
 .. _`SmsSluzba`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SmsSluzba/README.md
 .. _`SpotHit`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SpotHit/README.md
 .. _`Telegram`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Telegram/README.md

From 858f548a0db0c335578be3307bd664e06aa98615 Mon Sep 17 00:00:00 2001
From: Antoine M <amakdessi@me.com>
Date: Mon, 26 Feb 2024 07:07:42 +0100
Subject: [PATCH 178/747] chore: document minor upgrade with latest versions

follows https://github.com/symfony/symfony-docs/pull/19599
---
 setup/upgrade_minor.rst | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/setup/upgrade_minor.rst b/setup/upgrade_minor.rst
index 9e8c6943d1f..ec00e142b82 100644
--- a/setup/upgrade_minor.rst
+++ b/setup/upgrade_minor.rst
@@ -1,4 +1,4 @@
-Upgrading a Minor Version (e.g. 5.0.0 to 5.1.0)
+Upgrading a Minor Version (e.g. 6.3.0 to 6.4.0)
 ===============================================
 
 If you're upgrading a minor version (where the middle number changes), then
@@ -21,7 +21,7 @@ There are two steps to upgrading a minor version:
 The ``composer.json`` file is configured to allow Symfony packages to be
 upgraded to patch versions. But to upgrade to a new minor version, you will
 probably need to update the version constraint next to each library starting
-``symfony/``. Suppose you are upgrading from Symfony 5.3 to 5.4:
+``symfony/``. Suppose you are upgrading from Symfony 6.3 to 6.4:
 
 .. code-block:: diff
 
@@ -29,19 +29,17 @@ probably need to update the version constraint next to each library starting
           "...": "...",
 
           "require": {
-    -         "symfony/cache": "5.3.*",
-    +         "symfony/cache": "5.4.*",
-    -         "symfony/config": "5.3.*",
-    +         "symfony/config": "5.4.*",
-    -         "symfony/console": "5.3.*",
-    +         "symfony/console": "5.4.*",
+    -         "symfony/config": "6.3.*",
+    +         "symfony/config": "6.4.*",
+    -         "symfony/console": "6.3.*",
+    +         "symfony/console": "6.4.*",
               "...": "...",
 
               "...": "A few libraries starting with
                       symfony/ follow their own versioning scheme. You
                       do not need to update these versions: you can
                       upgrade them independently whenever you want",
-              "symfony/monolog-bundle": "^3.5",
+              "symfony/monolog-bundle": "^3.10",
           },
           "...": "...",
       }
@@ -54,8 +52,8 @@ Your ``composer.json`` file should also have an ``extra`` block that you will
       "extra": {
           "symfony": {
               "...": "...",
-    -         "require": "5.3.*"
-    +         "require": "5.4.*"
+    -         "require": "6.3.*"
+    +         "require": "6.4.*"
           }
       }
 
@@ -79,7 +77,7 @@ to your code to get everything working. Additionally, some features you're
 using might still work, but might now be deprecated. While that's fine,
 if you know about these deprecations, you can start to fix them over time.
 
-Every version of Symfony comes with an UPGRADE file (e.g. `UPGRADE-5.4.md`_)
+Every version of Symfony comes with an UPGRADE file (e.g. `UPGRADE-6.4.md`_)
 included in the Symfony directory that describes these changes. If you follow
 the instructions in the document and update your code accordingly, it should be
 safe to update in the future.
@@ -97,5 +95,5 @@ These documents can also be found in the `Symfony Repository`_.
 .. include:: /setup/_update_recipes.rst.inc
 
 .. _`Symfony Repository`: https://github.com/symfony/symfony
-.. _`UPGRADE-5.4.md`: https://github.com/symfony/symfony/blob/5.4/UPGRADE-5.4.md
+.. _`UPGRADE-6.4.md`: https://github.com/symfony/symfony/blob/6.4/UPGRADE-6.4.md
 .. _`Rector`: https://github.com/rectorphp/rector

From cbac28f28e9e8c9ac236717730057db8ff3ae613 Mon Sep 17 00:00:00 2001
From: Antoine M <amakdessi@me.com>
Date: Mon, 26 Feb 2024 07:13:01 +0100
Subject: [PATCH 179/747] chore: document major upgrade with latest versions

ref https://github.com/symfony/symfony-docs/pull/19600
---
 setup/upgrade_major.rst | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/setup/upgrade_major.rst b/setup/upgrade_major.rst
index 9e18c88ccd6..13f6feab6d1 100644
--- a/setup/upgrade_major.rst
+++ b/setup/upgrade_major.rst
@@ -1,4 +1,4 @@
-Upgrading a Major Version (e.g. 5.4.0 to 6.0.0)
+Upgrading a Major Version (e.g. 6.4.0 to 7.0.0)
 ===============================================
 
 Every two years, Symfony releases a new major version release (the first number
@@ -27,10 +27,10 @@ backwards incompatible changes. To accomplish this, the "old" (e.g. functions,
 classes, etc) code still works, but is marked as *deprecated*, indicating that
 it will be removed/changed in the future and that you should stop using it.
 
-When the major version is released (e.g. 6.0.0), all deprecated features and
+When the major version is released (e.g. 7.0.0), all deprecated features and
 functionality are removed. So, as long as you've updated your code to stop
 using these deprecated features in the last version before the major (e.g.
-``5.4.*``), you should be able to upgrade without a problem. That means that
+``6.4.*``), you should be able to upgrade without a problem. That means that
 you should first :doc:`upgrade to the last minor version </setup/upgrade_minor>`
 (e.g. 5.4) so that you can see *all* the deprecations.
 
@@ -107,7 +107,7 @@ done!
 .. sidebar:: Using the Weak Deprecations Mode
 
     Sometimes, you can't fix all deprecations (e.g. something was deprecated
-    in 5.4 and you still need to support 5.3). In these cases, you can still
+    in 6.4 and you still need to support 6.3). In these cases, you can still
     use the bridge to fix as many deprecations as possible and then allow
     more of them to make your tests pass again. You can do this by using the
     ``SYMFONY_DEPRECATIONS_HELPER`` env variable:
@@ -144,12 +144,10 @@ starting with ``symfony/`` to the new major version:
           "...": "...",
 
           "require": {
-    -         "symfony/cache": "5.4.*",
-    +         "symfony/cache": "6.0.*",
-    -         "symfony/config": "5.4.*",
-    +         "symfony/config": "6.0.*",
-    -         "symfony/console": "5.4.*",
-    +         "symfony/console": "6.0.*",
+    -         "symfony/config": "6.4.*",
+    +         "symfony/config": "7.0.*",
+    -         "symfony/console": "6.4.*",
+    +         "symfony/console": "7.0.*",
               "...": "...",
 
               "...": "A few libraries starting with symfony/ follow their own
@@ -157,22 +155,22 @@ starting with ``symfony/`` to the new major version:
                       symfony/ux-[...], symfony/[...]-bundle).
                       You do not need to update these versions: you can
                       upgrade them independently whenever you want",
-              "symfony/monolog-bundle": "^3.5",
+              "symfony/monolog-bundle": "^3.10",
           },
           "...": "...",
       }
 
 At the bottom of your ``composer.json`` file, in the ``extra`` block you can
 find a data setting for the Symfony version. Make sure to also upgrade
-this one. For instance, update it to ``6.0.*`` to upgrade to Symfony 6.0:
+this one. For instance, update it to ``7.0.*`` to upgrade to Symfony 7.0:
 
 .. code-block:: diff
 
       "extra": {
           "symfony": {
               "allow-contrib": false,
-    -       "require": "5.4.*"
-    +       "require": "6.0.*"
+    -       "require": "6.4.*"
+    +       "require": "7.0.*"
           }
       }
 
@@ -215,13 +213,13 @@ included in the Symfony repository for any BC break that you need to be aware of
 Upgrading to Symfony 6: Add Native Return Types
 -----------------------------------------------
 
-Symfony 6 will come with native PHP return types to (almost all) methods.
+Symfony 6 and Symfony 6 have come with native PHP return types to (almost all) methods.
 
 In PHP, if the parent has a return type declaration, any class implementing
 or overriding the method must have the return type as well. However, you
 can add a return type before the parent adds one. This means that it is
 important to add the native PHP return types to your classes before
-upgrading to Symfony 6.0. Otherwise, you will get incompatible declaration
+upgrading to Symfony 6.0 or 7.0. Otherwise, you will get incompatible declaration
 errors.
 
 When debug mode is enabled (typically in the dev and test environment),

From 3dd28c0de085154c76848717267ade1ae6f09d4e Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 26 Feb 2024 09:08:27 +0100
Subject: [PATCH 180/747] [Clock] Introduce `get/setMicroseconds()`

---
 components/clock.rst | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/components/clock.rst b/components/clock.rst
index b803c78e29d..d3879fba84e 100644
--- a/components/clock.rst
+++ b/components/clock.rst
@@ -235,6 +235,23 @@ The constructor also allows setting a timezone or custom referenced date::
     error handling across versions of PHP, thanks to polyfilling `PHP 8.3's behavior`_
     on the topic.
 
+``DatePoint`` also allows to set and get the microsecond part of the date and time::
+
+    $datePoint = new DatePoint();
+    $datePoint->setMicroseconds(345);
+    $microseconds = $datePoint->getMicroseconds();
+
+.. note::
+
+    This feature polyfills PHP 8.4's behavior on the topic, as microseconds manipulation
+    is not available in previous versions of PHP.
+
+.. versionadded:: 7.1
+
+    The :method:`Symfony\\Component\\Clock\\DatePoint::setMicroseconds` and
+    :method:`Symfony\\Component\\Clock\\DatePoint::getMicroseconds` methods were
+    introduced in Symfony 7.1.
+
 .. _clock_writing-tests:
 
 Writing Time-Sensitive Tests

From 657ba77f68175293cbbabd2c789ddc9e89d44cb6 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 26 Feb 2024 13:33:08 +0100
Subject: [PATCH 181/747] Minor fix

---
 setup/upgrade_major.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/setup/upgrade_major.rst b/setup/upgrade_major.rst
index 13f6feab6d1..13f839f36e1 100644
--- a/setup/upgrade_major.rst
+++ b/setup/upgrade_major.rst
@@ -213,7 +213,7 @@ included in the Symfony repository for any BC break that you need to be aware of
 Upgrading to Symfony 6: Add Native Return Types
 -----------------------------------------------
 
-Symfony 6 and Symfony 6 have come with native PHP return types to (almost all) methods.
+Symfony 6 and Symfony 7 added native PHP return types to (almost all) methods.
 
 In PHP, if the parent has a return type declaration, any class implementing
 or overriding the method must have the return type as well. However, you

From f5e545fd7f6640673f7f9524227fbc7934f172d2 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Tue, 5 Mar 2024 11:41:48 +0100
Subject: [PATCH 182/747] remove outdated directive

---
 frontend/asset_mapper.rst | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index 8815126dd26..31bbf3718c9 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -233,11 +233,6 @@ You can update your third-party packages to their current versions by running:
     $ php bin/console importmap:update bootstrap lodash
     $ php bin/console importmap:outdated bootstrap lodash
 
-.. versionadded:: 6.4
-
-    The ``importmap:install`` and ``importmap:outdated`` commands were introduced
-    in Symfony 6.4.
-
 How does the importmap Work?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From effeaf7a38f949722ad319222a5c9c69d2f4c0b8 Mon Sep 17 00:00:00 2001
From: Simon <smn.andre@gmail.com>
Date: Sat, 9 Mar 2024 08:55:33 +0100
Subject: [PATCH 183/747] Replace Webpack with AssetMapper

---
 templates.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates.rst b/templates.rst
index 3ba9b9f59a5..05de5856878 100644
--- a/templates.rst
+++ b/templates.rst
@@ -330,7 +330,7 @@ Build, Versioning & More Advanced CSS, JavaScript and Image Handling
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 For help building, versioning and minifying your JavaScript and
-CSS assets in a modern way, read about :doc:`Symfony's Webpack Encore </frontend>`.
+CSS assets in a modern way, read about :doc:`Symfony's Asset Mapper </frontend>`.
 
 .. _twig-app-variable:
 

From ea8efb0d8d05684afd0bdc2ab71dfbbe014973c8 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Mon, 11 Mar 2024 08:16:57 +0100
Subject: [PATCH 184/747] update method names to reflect latest code changes

---
 components/clock.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/components/clock.rst b/components/clock.rst
index d3879fba84e..45ec484eef5 100644
--- a/components/clock.rst
+++ b/components/clock.rst
@@ -238,8 +238,8 @@ The constructor also allows setting a timezone or custom referenced date::
 ``DatePoint`` also allows to set and get the microsecond part of the date and time::
 
     $datePoint = new DatePoint();
-    $datePoint->setMicroseconds(345);
-    $microseconds = $datePoint->getMicroseconds();
+    $datePoint->setMicrosecond(345);
+    $microseconds = $datePoint->getMicrosecond();
 
 .. note::
 
@@ -248,8 +248,8 @@ The constructor also allows setting a timezone or custom referenced date::
 
 .. versionadded:: 7.1
 
-    The :method:`Symfony\\Component\\Clock\\DatePoint::setMicroseconds` and
-    :method:`Symfony\\Component\\Clock\\DatePoint::getMicroseconds` methods were
+    The :method:`Symfony\\Component\\Clock\\DatePoint::setMicrosecond` and
+    :method:`Symfony\\Component\\Clock\\DatePoint::getMicrosecond` methods were
     introduced in Symfony 7.1.
 
 .. _clock_writing-tests:

From bbe6d9133aaaec4cf870f109b8f8c4d77e127a31 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aur=C3=A9lien=20Pillevesse?= <aurelienpillevesse@hotmail.fr>
Date: Mon, 11 Mar 2024 09:06:22 +0100
Subject: [PATCH 185/747] Update pull_requests.rst

---
 contributing/code/pull_requests.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contributing/code/pull_requests.rst b/contributing/code/pull_requests.rst
index 95ee6bb89a6..7c9ab2579a5 100644
--- a/contributing/code/pull_requests.rst
+++ b/contributing/code/pull_requests.rst
@@ -31,7 +31,7 @@ Before working on Symfony, setup a friendly environment with the following
 software:
 
 * Git;
-* PHP version 7.2.5 or above.
+* PHP version 8.2 or above.
 
 Configure Git
 ~~~~~~~~~~~~~

From 075c29fa816c1a29c9d23d6418950b7e67bd2e9e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aur=C3=A9lien=20Pillevesse?= <aurelienpillevesse@hotmail.fr>
Date: Sun, 10 Mar 2024 15:41:43 +0100
Subject: [PATCH 186/747] Update contributing/code/tests.rst page

---
 contributing/code/tests.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contributing/code/tests.rst b/contributing/code/tests.rst
index e6af1170e3d..58b4aa74d61 100644
--- a/contributing/code/tests.rst
+++ b/contributing/code/tests.rst
@@ -32,7 +32,7 @@ tests, such as Doctrine, Twig and Monolog. To do so,
 
     .. code-block:: terminal
 
-        $ COMPOSER_ROOT_VERSION=6.4.x-dev composer update
+        $ COMPOSER_ROOT_VERSION=7.0.x-dev composer update
 
 .. _running:
 

From 3b2a5bd3499315bf60e668f1bd3a9bf9dfa27758 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 11 Mar 2024 09:30:53 +0100
Subject: [PATCH 187/747] Update the test article of the contribution guide

---
 contributing/code/tests.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contributing/code/tests.rst b/contributing/code/tests.rst
index 58b4aa74d61..08f6bc5df12 100644
--- a/contributing/code/tests.rst
+++ b/contributing/code/tests.rst
@@ -32,7 +32,7 @@ tests, such as Doctrine, Twig and Monolog. To do so,
 
     .. code-block:: terminal
 
-        $ COMPOSER_ROOT_VERSION=7.0.x-dev composer update
+        $ COMPOSER_ROOT_VERSION=7.1.x-dev composer update
 
 .. _running:
 

From 3a6e5ec8f484fa8fe8d57309676537bf5416241d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aur=C3=A9lien=20Pillevesse?= <aurelienpillevesse@hotmail.fr>
Date: Mon, 11 Mar 2024 09:05:39 +0100
Subject: [PATCH 188/747] Update pull_requests.rst

---
 contributing/code/pull_requests.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contributing/code/pull_requests.rst b/contributing/code/pull_requests.rst
index 7b51b2ab3cb..7c9ab2579a5 100644
--- a/contributing/code/pull_requests.rst
+++ b/contributing/code/pull_requests.rst
@@ -31,7 +31,7 @@ Before working on Symfony, setup a friendly environment with the following
 software:
 
 * Git;
-* PHP version 8.1 or above.
+* PHP version 8.2 or above.
 
 Configure Git
 ~~~~~~~~~~~~~

From 876cbc034f8a327277395d762af5dd63542259b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20Andr=C3=A9?= <smn.andre@gmail.com>
Date: Sat, 3 Feb 2024 15:57:55 +0100
Subject: [PATCH 189/747] [Emoji] Emoji component

---
 components/emoji.rst | 122 +++++++++++++++++++++++++++++++++++++++++++
 components/intl.rst  |  57 ++++----------------
 2 files changed, 131 insertions(+), 48 deletions(-)
 create mode 100644 components/emoji.rst

diff --git a/components/emoji.rst b/components/emoji.rst
new file mode 100644
index 00000000000..b3f725a2585
--- /dev/null
+++ b/components/emoji.rst
@@ -0,0 +1,122 @@
+The Emoji Component
+===================
+
+    The Emoji component provides utilities to work with emoji characters and
+    sequences from the `Unicode CLDR dataset`_.
+
+Installation
+------------
+
+.. code-block:: terminal
+
+    $ composer require symfony/emoji
+
+.. include:: /components/require_autoload.rst.inc
+
+
+Emoji Transliteration
+---------------------
+
+The ``EmojiTransliterator`` class offers a way to translate emojis into their
+textual representation in all languages based on the `Unicode CLDR dataset`_::
+
+    use Symfony\Component\Emoji\EmojiTransliterator;
+
+    // Describe emojis in English
+    $transliterator = EmojiTransliterator::create('en');
+    $transliterator->transliterate('Menus with 🍕 or 🍝');
+    // => 'Menus with pizza or spaghetti'
+
+    // Describe emojis in Ukrainian
+    $transliterator = EmojiTransliterator::create('uk');
+    $transliterator->transliterate('Menus with 🍕 or 🍝');
+    // => 'Menus with піца or спагеті'
+
+
+The ``EmojiTransliterator`` also provides special locales that convert emojis to
+short codes and vice versa in specific platforms, such as GitHub and Slack.
+
+GitHub
+~~~~~~
+
+Convert GitHub emojis to short codes with the ``emoji-github`` locale::
+
+    $transliterator = EmojiTransliterator::create('emoji-github');
+    $transliterator->transliterate('Teenage 🐢 really love 🍕');
+    // => 'Teenage :turtle: really love :pizza:'
+
+Convert GitHub short codes to emojis with the ``github-emoji`` locale::
+
+    $transliterator = EmojiTransliterator::create('github-emoji');
+    $transliterator->transliterate('Teenage :turtle: really love :pizza:');
+    // => 'Teenage 🐢 really love 🍕'
+
+Slack
+~~~~~
+
+Convert Slack emojis to short codes with the ``emoji-slack`` locale::
+
+    $transliterator = EmojiTransliterator::create('emoji-slack');
+    $transliterator->transliterate('Menus with 🥗 or 🧆');
+    // => 'Menus with :green_salad: or :falafel:'
+
+Convert Slack short codes to emojis with the ``slack-emoji`` locale::
+
+    $transliterator = EmojiTransliterator::create('slack-emoji');
+    $transliterator->transliterate('Menus with :green_salad: or :falafel:');
+    // => 'Menus with 🥗 or 🧆'
+
+
+Emoji Slugger
+-------------
+
+Combine the emoji transliterator with the :doc:`/components/string`
+to improve the slugs of contents that include emojis (e.g. for URLs).
+
+Call the ``AsciiSlugger::withEmoji()`` method to enable the emoji transliterator in the Slugger::
+
+    use Symfony\Component\String\Slugger\AsciiSlugger;
+
+    $slugger = new AsciiSlugger();
+    $slugger = $slugger->withEmoji();
+
+    $slug = $slugger->slug('a 😺, 🐈‍⬛, and a 🦁 go to 🏞️', '-', 'en');
+    // $slug = 'a-grinning-cat-black-cat-and-a-lion-go-to-national-park';
+
+    $slug = $slugger->slug('un 😺, 🐈‍⬛, et un 🦁 vont au 🏞️', '-', 'fr');
+    // $slug = 'un-chat-qui-sourit-chat-noir-et-un-tete-de-lion-vont-au-parc-national';
+
+.. tip::
+
+    Integrating the Emoji Component with the String component is straightforward and requires no additional
+    configuration.string.
+
+Removing Emojis
+---------------
+
+The ``EmojiTransliterator`` can also be used to remove all emojis from a string, via the
+special ``strip`` locale::
+
+    use Symfony\Component\Emoji\EmojiTransliterator;
+
+    $transliterator = EmojiTransliterator::create('strip');
+    $transliterator->transliterate('🎉Hey!🥳 🎁Happy Birthday!🎁');
+    // => 'Hey! Happy Birthday!'
+
+Disk space
+----------
+
+The data needed to store the transliteration of all emojis (~5,000) into all
+languages take a considerable disk space.
+
+If you need to save disk space (e.g. because you deploy to some service with tight
+size constraints), run this command (e.g. as an automated script after ``composer install``)
+to compress the internal Symfony emoji data files using the PHP ``zlib`` extension:
+
+.. code-block:: terminal
+
+    # adjust the path to the 'compress' binary based on your application installation
+    $ php ./vendor/symfony/emoji/Resources/bin/compress
+
+
+.. _`Unicode CLDR dataset`: https://github.com/unicode-org/cldr
diff --git a/components/intl.rst b/components/intl.rst
index bbd088c830e..768ea30903c 100644
--- a/components/intl.rst
+++ b/components/intl.rst
@@ -28,7 +28,6 @@ This component provides the following ICU data:
 * `Locales`_
 * `Currencies`_
 * `Timezones`_
-* `Emoji Transliteration`_
 
 Language and Script Names
 ~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -386,56 +385,19 @@ to catching the exception, you can also check if a given timezone ID is valid::
 Emoji Transliteration
 ~~~~~~~~~~~~~~~~~~~~~
 
-The ``EmojiTransliterator`` class provides a utility to translate emojis into
-their textual representation in all languages based on the `Unicode CLDR dataset`_::
+.. note::
 
-    use Symfony\Component\Intl\Transliterator\EmojiTransliterator;
+    The ``EmojiTransliterator`` class provides a utility to translate emojis into
+    their textual representation in all languages based on the Unicode CLDR dataset.
 
-    // describe emojis in English
-    $transliterator = EmojiTransliterator::create('en');
-    $transliterator->transliterate('Menus with 🍕 or 🍝');
-    // => 'Menus with pizza or spaghetti'
+Discover all the available Emoji manipulations in the :doc:`component documentation </components/emoji>`.
 
-    // describe emojis in Ukrainian
-    $transliterator = EmojiTransliterator::create('uk');
-    $transliterator->transliterate('Menus with 🍕 or 🍝');
-    // => 'Menus with піца or спагеті'
-
-The ``EmojiTransliterator`` class also provides two extra catalogues: ``github``
-and ``slack`` that converts any emojis to the corresponding short code in those
-platforms::
-
-    use Symfony\Component\Intl\Transliterator\EmojiTransliterator;
-
-    // describe emojis in Slack short code
-    $transliterator = EmojiTransliterator::create('slack');
-    $transliterator->transliterate('Menus with 🥗 or 🧆');
-    // => 'Menus with :green_salad: or :falafel:'
-
-    // describe emojis in Github short code
-    $transliterator = EmojiTransliterator::create('github');
-    $transliterator->transliterate('Menus with 🥗 or 🧆');
-    // => 'Menus with :green_salad: or :falafel:'
-
-Furthermore the ``EmojiTransliterator`` provides a special ``strip`` locale
-that removes all the emojis from a string::
-
-    use Symfony\Component\Intl\Transliterator\EmojiTransliterator;
-
-    $transliterator = EmojiTransliterator::create('strip');
-    $transliterator->transliterate('🎉Hey!🥳 🎁Happy Birthday!🎁');
-    // => 'Hey! Happy Birthday!'
-
-.. tip::
-
-    Combine this emoji transliterator with the :ref:`Symfony String slugger <string-slugger-emoji>`
-    to improve the slugs of contents that include emojis (e.g. for URLs).
+Disk space
+----------
 
-The data needed to store the transliteration of all emojis (~5,000) into all
-languages take a considerable disk space. If you need to save disk space (e.g.
-because you deploy to some service with tight size constraints), run this command
-(e.g. as an automated script after ``composer install``) to compress the internal
-Symfony emoji data files using the PHP ``zlib`` extension:
+If you need to save disk space (e.g. because you deploy to some service with tight size
+constraints), run this command (e.g. as an automated script after ``composer install``) to compress the
+internal Symfony Intl data files using the PHP ``zlib`` extension:
 
 .. code-block:: terminal
 
@@ -464,4 +426,3 @@ Learn more
 .. _`daylight saving time (DST)`: https://en.wikipedia.org/wiki/Daylight_saving_time
 .. _`ISO 639-1 alpha-2`: https://en.wikipedia.org/wiki/ISO_639-1
 .. _`ISO 639-2 alpha-3 (2T)`: https://en.wikipedia.org/wiki/ISO_639-2
-.. _`Unicode CLDR dataset`: https://github.com/unicode-org/cldr

From 9333df7a418202a9efb4e4cc62bc2698bf13aaa9 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 11 Mar 2024 10:51:49 +0100
Subject: [PATCH 190/747] Reorganize the Emoji component contents

---
 components/emoji.rst  | 122 ------------------------------------------
 components/string.rst |  99 +++++++++++++++++++++++++++++++++-
 2 files changed, 98 insertions(+), 123 deletions(-)
 delete mode 100644 components/emoji.rst

diff --git a/components/emoji.rst b/components/emoji.rst
deleted file mode 100644
index b3f725a2585..00000000000
--- a/components/emoji.rst
+++ /dev/null
@@ -1,122 +0,0 @@
-The Emoji Component
-===================
-
-    The Emoji component provides utilities to work with emoji characters and
-    sequences from the `Unicode CLDR dataset`_.
-
-Installation
-------------
-
-.. code-block:: terminal
-
-    $ composer require symfony/emoji
-
-.. include:: /components/require_autoload.rst.inc
-
-
-Emoji Transliteration
----------------------
-
-The ``EmojiTransliterator`` class offers a way to translate emojis into their
-textual representation in all languages based on the `Unicode CLDR dataset`_::
-
-    use Symfony\Component\Emoji\EmojiTransliterator;
-
-    // Describe emojis in English
-    $transliterator = EmojiTransliterator::create('en');
-    $transliterator->transliterate('Menus with 🍕 or 🍝');
-    // => 'Menus with pizza or spaghetti'
-
-    // Describe emojis in Ukrainian
-    $transliterator = EmojiTransliterator::create('uk');
-    $transliterator->transliterate('Menus with 🍕 or 🍝');
-    // => 'Menus with піца or спагеті'
-
-
-The ``EmojiTransliterator`` also provides special locales that convert emojis to
-short codes and vice versa in specific platforms, such as GitHub and Slack.
-
-GitHub
-~~~~~~
-
-Convert GitHub emojis to short codes with the ``emoji-github`` locale::
-
-    $transliterator = EmojiTransliterator::create('emoji-github');
-    $transliterator->transliterate('Teenage 🐢 really love 🍕');
-    // => 'Teenage :turtle: really love :pizza:'
-
-Convert GitHub short codes to emojis with the ``github-emoji`` locale::
-
-    $transliterator = EmojiTransliterator::create('github-emoji');
-    $transliterator->transliterate('Teenage :turtle: really love :pizza:');
-    // => 'Teenage 🐢 really love 🍕'
-
-Slack
-~~~~~
-
-Convert Slack emojis to short codes with the ``emoji-slack`` locale::
-
-    $transliterator = EmojiTransliterator::create('emoji-slack');
-    $transliterator->transliterate('Menus with 🥗 or 🧆');
-    // => 'Menus with :green_salad: or :falafel:'
-
-Convert Slack short codes to emojis with the ``slack-emoji`` locale::
-
-    $transliterator = EmojiTransliterator::create('slack-emoji');
-    $transliterator->transliterate('Menus with :green_salad: or :falafel:');
-    // => 'Menus with 🥗 or 🧆'
-
-
-Emoji Slugger
--------------
-
-Combine the emoji transliterator with the :doc:`/components/string`
-to improve the slugs of contents that include emojis (e.g. for URLs).
-
-Call the ``AsciiSlugger::withEmoji()`` method to enable the emoji transliterator in the Slugger::
-
-    use Symfony\Component\String\Slugger\AsciiSlugger;
-
-    $slugger = new AsciiSlugger();
-    $slugger = $slugger->withEmoji();
-
-    $slug = $slugger->slug('a 😺, 🐈‍⬛, and a 🦁 go to 🏞️', '-', 'en');
-    // $slug = 'a-grinning-cat-black-cat-and-a-lion-go-to-national-park';
-
-    $slug = $slugger->slug('un 😺, 🐈‍⬛, et un 🦁 vont au 🏞️', '-', 'fr');
-    // $slug = 'un-chat-qui-sourit-chat-noir-et-un-tete-de-lion-vont-au-parc-national';
-
-.. tip::
-
-    Integrating the Emoji Component with the String component is straightforward and requires no additional
-    configuration.string.
-
-Removing Emojis
----------------
-
-The ``EmojiTransliterator`` can also be used to remove all emojis from a string, via the
-special ``strip`` locale::
-
-    use Symfony\Component\Emoji\EmojiTransliterator;
-
-    $transliterator = EmojiTransliterator::create('strip');
-    $transliterator->transliterate('🎉Hey!🥳 🎁Happy Birthday!🎁');
-    // => 'Hey! Happy Birthday!'
-
-Disk space
-----------
-
-The data needed to store the transliteration of all emojis (~5,000) into all
-languages take a considerable disk space.
-
-If you need to save disk space (e.g. because you deploy to some service with tight
-size constraints), run this command (e.g. as an automated script after ``composer install``)
-to compress the internal Symfony emoji data files using the PHP ``zlib`` extension:
-
-.. code-block:: terminal
-
-    # adjust the path to the 'compress' binary based on your application installation
-    $ php ./vendor/symfony/emoji/Resources/bin/compress
-
-
-.. _`Unicode CLDR dataset`: https://github.com/unicode-org/cldr
diff --git a/components/string.rst b/components/string.rst
index 68362ed8654..08870881541 100644
--- a/components/string.rst
+++ b/components/string.rst
@@ -507,6 +507,101 @@ requested during the program execution. You can also create lazy strings from a
     // hash computation only if it's needed
     $lazyHash = LazyString::fromStringable(new Hash());
 
+Working with Emojis
+-------------------
+
+.. versionadded:: 7.1
+
+    The emoji component was introduced in Symfony 7.1.
+
+Symfony provides several utilities to work with emoji characters and sequences
+from the `Unicode CLDR dataset`_. They are available via the Emoji component,
+which you must first install in your application:
+
+.. code-block:: terminal
+
+    $ composer require symfony/emoji
+
+The data needed to store the transliteration of all emojis (~5,000) into all
+languages take a considerable disk space.
+
+If you need to save disk space (e.g. because you deploy to some service with tight
+size constraints), run this command (e.g. as an automated script after ``composer install``)
+to compress the internal Symfony emoji data files using the PHP ``zlib`` extension:
+
+.. code-block:: terminal
+
+    # adjust the path to the 'compress' binary based on your application installation
+    $ php ./vendor/symfony/emoji/Resources/bin/compress
+
+.. _string-emoji-transliteration:
+
+Emoji Transliteration
+~~~~~~~~~~~~~~~~~~~~~
+
+The ``EmojiTransliterator`` class offers a way to translate emojis into their
+textual representation in all languages based on the `Unicode CLDR dataset`_::
+
+    use Symfony\Component\Emoji\EmojiTransliterator;
+
+    // Describe emojis in English
+    $transliterator = EmojiTransliterator::create('en');
+    $transliterator->transliterate('Menus with 🍕 or 🍝');
+    // => 'Menus with pizza or spaghetti'
+
+    // Describe emojis in Ukrainian
+    $transliterator = EmojiTransliterator::create('uk');
+    $transliterator->transliterate('Menus with 🍕 or 🍝');
+    // => 'Menus with піца or спагеті'
+
+
+The ``EmojiTransliterator`` also provides special locales that convert emojis to
+short codes and vice versa in specific platforms, such as GitHub and Slack.
+
+GitHub Emoji Transliteration
+............................
+
+Convert GitHub emojis to short codes with the ``emoji-github`` locale::
+
+    $transliterator = EmojiTransliterator::create('emoji-github');
+    $transliterator->transliterate('Teenage 🐢 really love 🍕');
+    // => 'Teenage :turtle: really love :pizza:'
+
+Convert GitHub short codes to emojis with the ``github-emoji`` locale::
+
+    $transliterator = EmojiTransliterator::create('github-emoji');
+    $transliterator->transliterate('Teenage :turtle: really love :pizza:');
+    // => 'Teenage 🐢 really love 🍕'
+
+Slack Emoji Transliteration
+...........................
+
+Convert Slack emojis to short codes with the ``emoji-slack`` locale::
+
+    $transliterator = EmojiTransliterator::create('emoji-slack');
+    $transliterator->transliterate('Menus with 🥗 or 🧆');
+    // => 'Menus with :green_salad: or :falafel:'
+
+Convert Slack short codes to emojis with the ``slack-emoji`` locale::
+
+    $transliterator = EmojiTransliterator::create('slack-emoji');
+    $transliterator->transliterate('Menus with :green_salad: or :falafel:');
+    // => 'Menus with 🥗 or 🧆'
+
+Removing Emojis
+~~~~~~~~~~~~~~~
+
+The ``EmojiTransliterator`` can also be used to remove all emojis from a string,
+via the special ``strip`` locale::
+
+    use Symfony\Component\Emoji\EmojiTransliterator;
+
+    $transliterator = EmojiTransliterator::create('strip');
+    $transliterator->transliterate('🎉Hey!🥳 🎁Happy Birthday!🎁');
+    // => 'Hey! Happy Birthday!'
+
+.. _string-slugger:
+
 Slugger
 -------
 
@@ -579,7 +674,8 @@ the injected slugger is the same as the request locale::
 Slug Emojis
 ~~~~~~~~~~~
 
-You can transform any emojis into their textual representation::
+You can also combine the :ref:`emoji transliterator <string-emoji-transliteration>`
+with the slugger to transform any emojis into their textual representation::
 
     use Symfony\Component\String\Slugger\AsciiSlugger;
 
@@ -648,3 +744,4 @@ possible to determine a unique singular/plural form for the given word.
 .. _`Code points`: https://en.wikipedia.org/wiki/Code_point
 .. _`Grapheme clusters`: https://en.wikipedia.org/wiki/Grapheme
 .. _`Unicode equivalence`: https://en.wikipedia.org/wiki/Unicode_equivalence
+.. _`Unicode CLDR dataset`: https://github.com/unicode-org/cldr

From 9de3da7d84231fb3eebc9aa8a2c2b3b0ebaf11a7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aur=C3=A9lien=20Pillevesse?= <aurelienpillevesse@hotmail.fr>
Date: Mon, 11 Mar 2024 13:13:30 +0100
Subject: [PATCH 191/747] Update setup.rst

---
 setup.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/setup.rst b/setup.rst
index 6ed508d771b..90a89e78e8a 100644
--- a/setup.rst
+++ b/setup.rst
@@ -48,10 +48,10 @@ application:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ symfony new my_project_directory --version="7.0.*" --webapp
+    $ symfony new my_project_directory --version="7.1.*" --webapp
 
     # run this if you are building a microservice, console application or API
-    $ symfony new my_project_directory --version="7.0.*"
+    $ symfony new my_project_directory --version="7.1.*"
 
 The only difference between these two commands is the number of packages
 installed by default. The ``--webapp`` option installs extra packages to give
@@ -63,12 +63,12 @@ Symfony application using Composer:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ composer create-project symfony/skeleton:"7.0.*" my_project_directory
+    $ composer create-project symfony/skeleton:"7.1.*" my_project_directory
     $ cd my_project_directory
     $ composer require webapp
 
     # run this if you are building a microservice, console application or API
-    $ composer create-project symfony/skeleton:"7.0.*" my_project_directory
+    $ composer create-project symfony/skeleton:"7.1.*" my_project_directory
 
 No matter which command you run to create the Symfony application. All of them
 will create a new ``my_project_directory/`` directory, download some dependencies

From 46a9a052c2455ee6290693daf2f7f6d5702fc53c Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Mon, 11 Mar 2024 13:44:36 +0100
Subject: [PATCH 192/747] fix build

---
 components/intl.rst   | 2 +-
 components/string.rst | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/components/intl.rst b/components/intl.rst
index 768ea30903c..0cf99591369 100644
--- a/components/intl.rst
+++ b/components/intl.rst
@@ -390,7 +390,7 @@ Emoji Transliteration
     The ``EmojiTransliterator`` class provides a utility to translate emojis into
     their textual representation in all languages based on the Unicode CLDR dataset.
 
-Discover all the available Emoji manipulations in the :doc:`component documentation </components/emoji>`.
+Discover all the available Emoji manipulations in the :ref:`component documentation <working-with-emojis>`.
 
 Disk space
 ----------
diff --git a/components/string.rst b/components/string.rst
index 08870881541..56af5719170 100644
--- a/components/string.rst
+++ b/components/string.rst
@@ -507,6 +507,8 @@ requested during the program execution. You can also create lazy strings from a
     // hash computation only if it's needed
     $lazyHash = LazyString::fromStringable(new Hash());
 
+.. _working-with-emojis:
+
 Working with Emojis
 -------------------
 

From 7040512e84182f28aa95abf3bce4ca058ddd65ec Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 12 Mar 2024 09:36:00 +0100
Subject: [PATCH 193/747] Update build.php

---
 _build/build.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/_build/build.php b/_build/build.php
index 454553d459e..6a1ac4642f0 100755
--- a/_build/build.php
+++ b/_build/build.php
@@ -20,7 +20,7 @@
 
         $outputDir = __DIR__.'/output';
         $buildConfig = (new BuildConfig())
-            ->setSymfonyVersion('6.4')
+            ->setSymfonyVersion('7.0')
             ->setContentDir(__DIR__.'/..')
             ->setOutputDir($outputDir)
             ->setImagesDir(__DIR__.'/output/_images')

From ef3b01df3ce14ac49ca90d961f300a9463c863fb Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 12 Mar 2024 09:37:21 +0100
Subject: [PATCH 194/747] Update build.php

---
 _build/build.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/_build/build.php b/_build/build.php
index 6a1ac4642f0..5298abe779a 100755
--- a/_build/build.php
+++ b/_build/build.php
@@ -20,7 +20,7 @@
 
         $outputDir = __DIR__.'/output';
         $buildConfig = (new BuildConfig())
-            ->setSymfonyVersion('7.0')
+            ->setSymfonyVersion('7.1')
             ->setContentDir(__DIR__.'/..')
             ->setOutputDir($outputDir)
             ->setImagesDir(__DIR__.'/output/_images')

From d4aed270931877b2fa5f008294c821a2593aa38b Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 13 Mar 2024 10:24:17 +0100
Subject: [PATCH 195/747] [String] Reorganize String component contents

---
 _build/redirection_map              |  3 ++-
 components/intl.rst                 |  9 +++------
 components/string.rst => string.rst | 14 ++++++++------
 3 files changed, 13 insertions(+), 13 deletions(-)
 rename components/string.rst => string.rst (98%)

diff --git a/_build/redirection_map b/_build/redirection_map
index 3b845d59ffe..34f3b7d166b 100644
--- a/_build/redirection_map
+++ b/_build/redirection_map
@@ -529,7 +529,7 @@
 /components/serializer#component-serializer-attributes-groups-annotations /components/serializer#component-serializer-attributes-groups-attributes
 /logging/monolog_regex_based_excludes /logging/monolog_exclude_http_codes
 /security/named_encoders /security/named_hashers
-/components/inflector /components/string#inflector
+/components/inflector /string#inflector
 /security/experimental_authenticators /security
 /security/user_provider /security/user_providers
 /security/reset_password /security/passwords#reset-password
@@ -566,3 +566,4 @@
 /messenger/handler_results /messenger#messenger-getting-handler-results
 /messenger/dispatch_after_current_bus /messenger#messenger-transactional-messages
 /messenger/multiple_buses /messenger#messenger-multiple-buses
+/components/string /string
diff --git a/components/intl.rst b/components/intl.rst
index 0cf99591369..d18ac21b10a 100644
--- a/components/intl.rst
+++ b/components/intl.rst
@@ -385,12 +385,9 @@ to catching the exception, you can also check if a given timezone ID is valid::
 Emoji Transliteration
 ~~~~~~~~~~~~~~~~~~~~~
 
-.. note::
-
-    The ``EmojiTransliterator`` class provides a utility to translate emojis into
-    their textual representation in all languages based on the Unicode CLDR dataset.
-
-Discover all the available Emoji manipulations in the :ref:`component documentation <working-with-emojis>`.
+Symfony provides utilities to translate emojis into their textual representation
+in all languages. Read the documentation on :ref:`working with emojis in strings <string-emoji-transliteration>`
+to learn more about this feature.
 
 Disk space
 ----------
diff --git a/components/string.rst b/string.rst
similarity index 98%
rename from components/string.rst
rename to string.rst
index 56af5719170..62336e461cf 100644
--- a/components/string.rst
+++ b/string.rst
@@ -1,11 +1,11 @@
-The String Component
-====================
+Creating and Manipulating Strings
+=================================
 
-    The String component provides a single object-oriented API to work with
-    three "unit systems" of strings: bytes, code points and grapheme clusters.
+Symfony provides an object-oriented API to work with Unicode strings (as bytes,
+code points and grapheme clusters). This API is available via the String component,
+which you must first install in your application:
 
-Installation
-------------
+.. _installation:
 
 .. code-block:: terminal
 
@@ -524,6 +524,8 @@ which you must first install in your application:
 
     $ composer require symfony/emoji
 
+.. include:: /components/require_autoload.rst.inc
+
 The data needed to store the transliteration of all emojis (~5,000) into all
 languages take a considerable disk space.
 

From 670b70ee456e7154d811d92bfabbd2fa7c2bbae0 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 14 Mar 2024 16:21:05 +0100
Subject: [PATCH 196/747] Remove some versionadded directives

---
 components/messenger.rst | 5 -----
 scheduler.rst            | 5 -----
 2 files changed, 10 deletions(-)

diff --git a/components/messenger.rst b/components/messenger.rst
index 8ec25d2c75f..a1c1e709e00 100644
--- a/components/messenger.rst
+++ b/components/messenger.rst
@@ -167,11 +167,6 @@ Here are some important envelope stamps that are shipped with the Symfony Messen
   differentiate it from messages created "manually". You can learn more about it
   in the :doc:`Scheduler documentation </scheduler>`.
 
-.. versionadded:: 6.4
-
-    The :class:`Symfony\\Component\\Messenger\\Stamp\\ScheduledStamp` was
-    introduced in Symfony 6.4.
-
 .. note::
 
     The :class:`Symfony\\Component\\Messenger\\Stamp\\ErrorDetailsStamp` stamp
diff --git a/scheduler.rst b/scheduler.rst
index 7a21d06ea9b..16346b4f566 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -885,11 +885,6 @@ When using the ``RedispatchMessage``, Symfony will attach a
 :class:`Symfony\\Component\\Messenger\\Stamp\\ScheduledStamp` to the message,
 helping you identify those messages when needed.
 
-.. versionadded:: 6.4
-
-    Automatically attaching a :class:`Symfony\\Component\\Messenger\\Stamp\\ScheduledStamp`
-    to redispatched messages was introduced in Symfony 6.4.
-
 .. _`Memoizing`: https://en.wikipedia.org/wiki/Memoization
 .. _`cron command-line utility`: https://en.wikipedia.org/wiki/Cron
 .. _`crontab.guru website`: https://crontab.guru/

From e94de7a5672dc87baa021cacdd3d05abb6d5e5b5 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 12 Mar 2024 10:04:12 +0100
Subject: [PATCH 197/747] [Workflow] Attach workflow configuration to tags

---
 service_container/tags.rst |  2 ++
 workflow.rst               | 13 +++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/service_container/tags.rst b/service_container/tags.rst
index ca36bde74e1..1900ce28fb2 100644
--- a/service_container/tags.rst
+++ b/service_container/tags.rst
@@ -458,6 +458,8 @@ or from your kernel::
     :ref:`components documentation <components-di-compiler-pass>` for more
     information.
 
+.. _tags_additional-attributes:
+
 Adding Additional Attributes on Tags
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/workflow.rst b/workflow.rst
index 7e45c7693c1..4e85c10087d 100644
--- a/workflow.rst
+++ b/workflow.rst
@@ -366,6 +366,17 @@ name.
     * ``workflow.workflow``: all workflows;
     * ``workflow.state_machine``: all state machines.
 
+    Note that workflow metadata are attached to tags under the
+    ``metatdata`` key, giving you more context and information about the workflow
+    at disposal. You can learn more about
+    :ref:`tag attributes <tags_additional-attributes>` and
+    :ref:`storing workflow metadata <workflow_storing-metadata>`
+    in their dedicated sections.
+
+    .. versionadded:: 7.1
+
+        The attached configuration to the tag was introduced in Symfony 7.1.
+
 .. tip::
 
     You can find the list of available workflow services with the
@@ -1032,6 +1043,8 @@ The following example shows these functions in action:
         <span class="error">{{ blocker.message }}</span>
     {% endfor %}
 
+.. _workflow_storing-metadata:
+
 Storing Metadata
 ----------------
 

From 438031cfd908517c3ced245ff6a0e76ecc963bcc Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 18 Mar 2024 11:00:42 +0100
Subject: [PATCH 198/747] Tweaks

---
 workflow.rst | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/workflow.rst b/workflow.rst
index 4e85c10087d..65c4f827a0f 100644
--- a/workflow.rst
+++ b/workflow.rst
@@ -366,12 +366,10 @@ name.
     * ``workflow.workflow``: all workflows;
     * ``workflow.state_machine``: all state machines.
 
-    Note that workflow metadata are attached to tags under the
-    ``metatdata`` key, giving you more context and information about the workflow
-    at disposal. You can learn more about
-    :ref:`tag attributes <tags_additional-attributes>` and
-    :ref:`storing workflow metadata <workflow_storing-metadata>`
-    in their dedicated sections.
+    Note that workflow metadata are attached to tags under the ``metadata`` key,
+    giving you more context and information about the workflow at disposal.
+    Learn more about :ref:`tag attributes <tags_additional-attributes>` and
+    :ref:`storing workflow metadata <workflow_storing-metadata>`.
 
     .. versionadded:: 7.1
 

From 742b2cceaeac7d7ef8ae47a21f9c6f597237a1cf Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 18 Mar 2024 17:30:13 +0100
Subject: [PATCH 199/747] [Filesystem] Document the readFile() method

---
 components/filesystem.rst | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/components/filesystem.rst b/components/filesystem.rst
index 8cdc2a34884..dabf3f81872 100644
--- a/components/filesystem.rst
+++ b/components/filesystem.rst
@@ -313,6 +313,22 @@ contents at the end of some file::
 If either the file or its containing directory doesn't exist, this method
 creates them before appending the contents.
 
+``readFile``
+~~~~~~~~~~~~
+
+.. versionadded:: 7.1
+
+    The ``readFile()`` method was introduced in Symfony 7.1.
+
+:method:`Symfony\\Component\\Filesystem\\Filesystem::readFile` returns all the
+contents of a file as a string. Unlike the :phpfunction:`file_get_contents` function
+from PHP, it throws an exception when the given file path is not readable and
+when passing the path to a directory instead of a file::
+
+    $contents = $filesystem->readFile('/some/path/to/file.txt');
+
+The ``$contents`` variable now stores all the contents of the ``file.txt`` file.
+
 Path Manipulation Utilities
 ---------------------------
 

From 6f05767d02593ebf2d47cfced08fabee1e0763b3 Mon Sep 17 00:00:00 2001
From: Benjamin Zaslavsky <benjamin.zaslavsky@gmail.com>
Date: Thu, 25 Jan 2024 09:54:48 +0100
Subject: [PATCH 200/747] [DependencyInjection] Add `#[Lazy]` attribute

---
 reference/attributes.rst            |  1 +
 service_container/lazy_services.rst | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/reference/attributes.rst b/reference/attributes.rst
index 08667e2a06f..015b8751834 100644
--- a/reference/attributes.rst
+++ b/reference/attributes.rst
@@ -37,6 +37,7 @@ Dependency Injection
 * :ref:`AutowireLocator <service-locator_autowire-locator>`
 * :ref:`AutowireServiceClosure <autowiring_closures>`
 * :ref:`Exclude <service-psr4-loader>`
+* :ref:`Lazy <lazy-services_configuration>`
 * :ref:`TaggedIterator <tags_reference-tagged-services>`
 * :ref:`TaggedLocator <service-subscribers-locators_defining-service-locator>`
 * :ref:`Target <autowiring-multiple-implementations-same-type>`
diff --git a/service_container/lazy_services.rst b/service_container/lazy_services.rst
index 46e939d4fac..4d21837e4ae 100644
--- a/service_container/lazy_services.rst
+++ b/service_container/lazy_services.rst
@@ -124,6 +124,32 @@ laziness, and supports lazy-autowiring of intersection types::
     ) {
     }
 
+Another possibility is to use the :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Lazy` attribute::
+
+    namespace App\Twig;
+
+    use Symfony\Component\DependencyInjection\Attribute\Lazy;
+    use Twig\Extension\ExtensionInterface;
+
+    #[Lazy]
+    class AppExtension implements ExtensionInterface
+    {
+        // ...
+    }
+
+This attribute can be used on a class or on a parameter which should be lazy-loaded, and has a parameter
+that also supports defining interfaces to proxy and intersection types::
+
+    public function __construct(
+        #[Lazy(FooInterface::class)]
+        FooInterface|BarInterface $foo,
+    ) {
+    }
+
+.. versionadded:: 7.1
+
+    The ``#[Lazy]`` attribute was introduced in Symfony 7.1.
+
 Interface Proxifying
 --------------------
 

From 0816f2b88a0aec8ddad0df640b94a2ae3b0f427e Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 21 Mar 2024 15:42:46 +0100
Subject: [PATCH 201/747] Tweaks

---
 service_container/lazy_services.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/service_container/lazy_services.rst b/service_container/lazy_services.rst
index ca883278453..41f27d8448f 100644
--- a/service_container/lazy_services.rst
+++ b/service_container/lazy_services.rst
@@ -137,8 +137,8 @@ Another possibility is to use the :class:`Symfony\\Component\\DependencyInjectio
         // ...
     }
 
-This attribute can be used on a class or on a parameter which should be lazy-loaded, and has a parameter
-that also supports defining interfaces to proxy and intersection types::
+This attribute can be applied to both class and parameters that should be lazy-loaded.
+It defines an optional parameter used to define interfaces for proxy and intersection types::
 
     public function __construct(
         #[Lazy(FooInterface::class)]

From 7afdaa339959baaa3e55a8ec2fe33f1d93fb2d84 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 26 Mar 2024 16:53:56 +0100
Subject: [PATCH 202/747] [Console] Mention `ArgvInput::getRawTokens`

---
 console/input.rst | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/console/input.rst b/console/input.rst
index 4d709c18825..f889926be59 100644
--- a/console/input.rst
+++ b/console/input.rst
@@ -311,6 +311,37 @@ The above code can be simplified as follows because ``false !== null``::
     $yell = ($optionValue !== false);
     $yellLouder = ($optionValue === 'louder');
 
+Fetching The Raw Command Input
+------------------------------
+
+Sometimes, you may need to fetch the raw input that was passed to the command.
+This is useful when you need to parse the input yourself or when you need to
+pass the input to another command without having to worry about the number
+of arguments or options defined in your own command. This can be achieved
+thanks to the
+:method:`Symfony\\Component\\Console\\Input\\ArgvInput::getRawTokens` method::
+
+    // ...
+    use Symfony\Component\Process\Process;
+
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        // pass the raw input of your command to the "ls" command
+        $process = new Process(['ls', ...$input->getRawTokens(true)]);
+        $process->setTty(true);
+        $process->mustRun();
+
+        // ...
+    }
+
+You can include the current command name in the raw tokens by passing ``true``
+to the ``getRawTokens`` method only parameter.
+
+.. versionadded:: 7.1
+
+    The :method:`Symfony\\Component\\Console\\Input\\ArgvInput::getRawTokens`
+    method was introduced in Symfony 7.1.
+
 Adding Argument/Option Value Completion
 ---------------------------------------
 

From 08a12ec0616af510e0325a2b21acea467d5ec7fe Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 25 Mar 2024 09:32:21 +0100
Subject: [PATCH 203/747] [Workflow] Document the EventNameTrait

---
 workflow.rst | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/workflow.rst b/workflow.rst
index 65c4f827a0f..f0c276a86f1 100644
--- a/workflow.rst
+++ b/workflow.rst
@@ -496,6 +496,7 @@ workflow leaves a place::
     use Psr\Log\LoggerInterface;
     use Symfony\Component\EventDispatcher\EventSubscriberInterface;
     use Symfony\Component\Workflow\Event\Event;
+    use Symfony\Component\Workflow\Event\LeaveEvent;
 
     class WorkflowLoggerSubscriber implements EventSubscriberInterface
     {
@@ -518,11 +519,24 @@ workflow leaves a place::
         public static function getSubscribedEvents(): array
         {
             return [
-                'workflow.blog_publishing.leave' => 'onLeave',
+                LeaveEvent::getName('blog_publishing') => 'onLeave',
+                // if you prefer, you can write the event name manually like this:
+                // 'workflow.blog_publishing.leave' => 'onLeave',
             ];
         }
     }
 
+.. tip::
+
+    All built-in workflow events define the ``getName(?string $workflowName, ?string $transitionOrPlaceName)``
+    method to build the full event name without having to deal with strings.
+    You can also use this method in your custom events via the
+    :class:`Symfony\\Component\\Workflow\\Event\\EventNameTrait`.
+
+    .. versionadded:: 7.1
+
+        The ``getName()`` method was introduced in Symfony 7.1.
+
 If some listeners update the context during a transition, you can retrieve
 it via the marking::
 

From 1aab03d5113790f068f54ba224ac429fda9891d2 Mon Sep 17 00:00:00 2001
From: Vincent Langlet <vincentlanglet@hotmail.fr>
Date: Fri, 22 Mar 2024 09:58:55 +0100
Subject: [PATCH 204/747] [Console] Add doc about lockableTrait

---
 console/lockable_trait.rst | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/console/lockable_trait.rst b/console/lockable_trait.rst
index 02f635f5788..19f30e86d96 100644
--- a/console/lockable_trait.rst
+++ b/console/lockable_trait.rst
@@ -43,4 +43,24 @@ that adds two convenient methods to lock and release commands::
         }
     }
 
+The LockableTrait will use the ``SemaphoreStore`` if available and will default
+to ``FlockStore`` otherwise. You can override this behavior by setting
+a ``$lockFactory`` property with your own lock factory::
+
+    // ...
+    use Symfony\Component\Console\Command\Command;
+    use Symfony\Component\Console\Command\LockableTrait;
+    use Symfony\Component\Lock\LockFactory;
+
+    class UpdateContentsCommand extends Command
+    {
+        use LockableTrait;
+
+        public function __construct(private LockFactory $lockFactory)
+        {
+        }
+
+        // ...
+    }
+
 .. _`locks`: https://en.wikipedia.org/wiki/Lock_(computer_science)

From b9b06084b6d809269e615ae295683c7a7575e72f Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 2 Apr 2024 08:26:03 +0200
Subject: [PATCH 205/747] Add the missing versionadded directive

---
 console/lockable_trait.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/console/lockable_trait.rst b/console/lockable_trait.rst
index 19f30e86d96..0f4a4900e17 100644
--- a/console/lockable_trait.rst
+++ b/console/lockable_trait.rst
@@ -63,4 +63,8 @@ a ``$lockFactory`` property with your own lock factory::
         // ...
     }
 
+.. versionadded::  7.1
+
+    The ``$lockFactory`` property was introduced in Symfony 7.1.
+
 .. _`locks`: https://en.wikipedia.org/wiki/Lock_(computer_science)

From dc57552a4f14eb3d87806b23140f1a10ea1e3f3d Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Thu, 28 Mar 2024 10:43:54 +0100
Subject: [PATCH 206/747] [Serializer] Mention
 `AbstractNormalizer::FILTER_BOOL`

---
 components/serializer.rst | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/components/serializer.rst b/components/serializer.rst
index 3bda0b0cf4f..a28464ffc04 100644
--- a/components/serializer.rst
+++ b/components/serializer.rst
@@ -700,8 +700,13 @@ deserializing objects::
     $serialized = $serializer->serialize(new Person('Kévin'), 'json');
     // {"customer_name": "Kévin"}
 
-Serializing Boolean Attributes
-------------------------------
+.. _serializing-boolean-attributes:
+
+Handling Boolean Attributes And Values
+--------------------------------------
+
+During Serialization
+~~~~~~~~~~~~~~~~~~~~
 
 If you are using isser methods (methods prefixed by ``is``, like
 ``App\Model\Person::isSportsperson()``), the Serializer component will
@@ -710,6 +715,34 @@ automatically detect and use it to serialize related attributes.
 The ``ObjectNormalizer`` also takes care of methods starting with ``has``, ``get``,
 and ``can``.
 
+During Deserialization
+~~~~~~~~~~~~~~~~~~~~~~
+
+PHP considers many different values as true or false. For example, the
+strings ``true``, ``1``, and ``yes`` are considered true, while
+``false``, ``0``, and ``no`` are considered false.
+
+When deserializing, the Serializer component can take care of this
+automatically. This can be done by using the ``AbstractNormalizer::FILTER_BOOL``
+context option::
+
+    use Acme\Person;
+    use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
+    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
+    use Symfony\Component\Serializer\Serializer;
+
+    $normalizer = new ObjectNormalizer();
+    $serializer = new Serializer([$normalizer]);
+
+    $data = $serializer->denormalize(['sportsperson' => 'yes'], Person::class, context: [AbstractNormalizer::FILTER_BOOL => true]);
+
+This context makes the deserialization process behave like the
+:phpfunction:`filter_var` function with the ``FILTER_VALIDATE_BOOL`` flag.
+
+.. versionadded:: 7.1
+
+    The ``AbstractNormalizer::FILTER_BOOL`` context option was introduced in Symfony 7.1.
+
 Using Callbacks to Serialize Properties with Object Instances
 -------------------------------------------------------------
 

From 5abfb8e3641ecf2f4965fdd12213d1a5efa5dbf9 Mon Sep 17 00:00:00 2001
From: Bram de Smidt <Bramw2003@users.noreply.github.com>
Date: Wed, 3 Apr 2024 14:36:54 +0200
Subject: [PATCH 207/747] fix: typo in proxy docs

---
 deployment/proxies.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/deployment/proxies.rst b/deployment/proxies.rst
index 82ea4dcffab..dcef631648f 100644
--- a/deployment/proxies.rst
+++ b/deployment/proxies.rst
@@ -156,7 +156,7 @@ subpath/subfolder of the reverse proxy.
 To fix this, you need to pass the subpath/subfolder route prefix of the reverse
 proxy to Symfony by setting the ``X-Forwarded-Prefix`` header. The header can
 normally be configured in your reverse proxy configuration. Configure
-``X-Forwared-Prefix`` as trusted header to be able to use this feature.
+``X-Forwarded-Prefix`` as trusted header to be able to use this feature.
 
 The ``X-Forwarded-Prefix`` is used by Symfony to prefix the base URL of request
 objects, which is used to generate absolute paths and URLs in Symfony applications.

From f68defc1f4307b61fca1e756983c6a4a06e2543e Mon Sep 17 00:00:00 2001
From: Quentin Devos <4972091+Okhoshi@users.noreply.github.com>
Date: Wed, 3 Apr 2024 22:43:01 +0200
Subject: [PATCH 208/747] [FrameworkBundle] Remove mention of inexistant
 `ignore_cache` option

Signed-off-by: Quentin Devos <4972091+Okhoshi@users.noreply.github.com>
---
 reference/configuration/framework.rst | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 5a7a5684fbc..57693ff0b1d 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -1514,15 +1514,7 @@ The directory where routing information will be cached. Can be set to
 .. deprecated:: 7.1
 
     Setting the ``cache_dir`` option is deprecated since Symfony 7.1. The routes
-    are now always cached in the ``%kernel.build_dir%`` directory. If you want
-    to disable route caching, set the ``ignore_cache`` option to ``true``.
-
-ignore_cache
-............
-
-**type**: ``boolean`` **default**: ``false``
-
-When this option is set to ``true``, routing information will not be cached.
+    are now always cached in the ``%kernel.build_dir%`` directory.
 
 secrets
 ~~~~~~~

From 265a69ccae8e8250255cf596bc42c357f77b4cfc Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Tue, 2 Apr 2024 20:52:04 +0200
Subject: [PATCH 209/747] [FrameworkBundle][HttpClient] Add
 ThrottlingHttpClient

---
 http_client.rst                       | 34 +++++++++++++++++++++++++++
 reference/configuration/framework.rst | 14 +++++++++++
 2 files changed, 48 insertions(+)

diff --git a/http_client.rst b/http_client.rst
index 1966dfba064..3a649f452fd 100644
--- a/http_client.rst
+++ b/http_client.rst
@@ -1474,6 +1474,40 @@ installed in your application::
 :class:`Symfony\\Component\\HttpClient\\CachingHttpClient` accepts a third argument
 to set the options of the :class:`Symfony\\Component\\HttpKernel\\HttpCache\\HttpCache`.
 
+Limit the Number of Requests
+----------------------------
+
+This component provides a :class:`Symfony\\Component\\HttpClient\\ThrottlingHttpClient`
+decorator that allows to limit the number of requests within a certain period.
+
+The implementation leverages the
+:class:`Symfony\\Component\\RateLimiter\\LimiterInterface` class under the hood
+so that the :doc:`Rate Limiter component </rate_limiter>` needs to be
+installed in your application::
+
+    use Symfony\Component\HttpClient\HttpClient;
+    use Symfony\Component\HttpClient\ThrottlingHttpClient;
+    use Symfony\Component\RateLimiter\LimiterInterface;
+
+    $rateLimiter = ...; // $rateLimiter is an instance of Symfony\Component\RateLimiter\LimiterInterface
+    $client = HttpClient::create();
+    $client = new ThrottlingHttpClient($client, $rateLimiter);
+
+    $requests = [];
+    for ($i = 0; $i < 100; $i++) {
+        $requests[] = $client->request('GET', 'https://example.com');
+    }
+
+    foreach ($requests as $request) {
+        // Depending on rate limiting policy, calls will be delayed
+        $output->writeln($request->getContent());
+    }
+
+.. versionadded:: 7.1
+
+    The :class:`Symfony\\Component\\HttpClient\\ThrottlingHttpClient` was
+    introduced in Symfony 7.1.
+
 Consuming Server-Sent Events
 ----------------------------
 
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 5a7a5684fbc..d61f94007a8 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -1174,6 +1174,20 @@ query
 An associative array of the query string values added to the URL before making
 the request. This value must use the format ``['parameter-name' => parameter-value, ...]``.
 
+rate_limiter
+............
+
+**type**: ``string``
+
+This option limit the number of requests within a certain period thanks
+to the :doc:`Rate Limiter component </rate_limiter>`.
+
+The rate limiter service ID you want to use.
+
+.. versionadded:: 7.1
+
+    The ``rate_limiter`` option was introduced in Symfony 7.1.
+
 resolve
 .......
 

From d49c1d71b885817d240828b22c55d1ab6c19a106 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 4 Apr 2024 10:04:30 +0200
Subject: [PATCH 210/747] Minor reword

---
 reference/configuration/framework.rst | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index d61f94007a8..e8db5e27eb6 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -1179,10 +1179,9 @@ rate_limiter
 
 **type**: ``string``
 
-This option limit the number of requests within a certain period thanks
-to the :doc:`Rate Limiter component </rate_limiter>`.
-
-The rate limiter service ID you want to use.
+The service ID of the rate limiter used to limit the number of HTTP requests
+within a certain period. The service must implement the
+:class:`Symfony\\Component\\RateLimiter\\LimiterInterface`.
 
 .. versionadded:: 7.1
 

From c41f6c6e74925a895a016246aa3148cd51d64ad4 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 4 Apr 2024 10:06:22 +0200
Subject: [PATCH 211/747] Minor grammar fix

---
 http_client.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/http_client.rst b/http_client.rst
index 3a649f452fd..c7c80ca57f3 100644
--- a/http_client.rst
+++ b/http_client.rst
@@ -1482,7 +1482,7 @@ decorator that allows to limit the number of requests within a certain period.
 
 The implementation leverages the
 :class:`Symfony\\Component\\RateLimiter\\LimiterInterface` class under the hood
-so that the :doc:`Rate Limiter component </rate_limiter>` needs to be
+so the :doc:`Rate Limiter component </rate_limiter>` needs to be
 installed in your application::
 
     use Symfony\Component\HttpClient\HttpClient;

From 0163c71fb5e24a299153035b67e37a36fdcd8e89 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Wed, 3 Apr 2024 22:33:49 +0200
Subject: [PATCH 212/747] [Emoji] Add the gitlab locale

---
 string.rst | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/string.rst b/string.rst
index 62336e461cf..b4f6d2d1be7 100644
--- a/string.rst
+++ b/string.rst
@@ -560,7 +560,7 @@ textual representation in all languages based on the `Unicode CLDR dataset`_::
 
 
 The ``EmojiTransliterator`` also provides special locales that convert emojis to
-short codes and vice versa in specific platforms, such as GitHub and Slack.
+short codes and vice versa in specific platforms, such as GitHub, Gitlab and Slack.
 
 GitHub Emoji Transliteration
 ............................
@@ -577,6 +577,21 @@ Convert GitHub short codes to emojis with the ``github-emoji`` locale::
     $transliterator->transliterate('Teenage :turtle: really love :pizza:');
     // => 'Teenage 🐢 really love 🍕'
 
+Gitlab Emoji Transliteration
+............................
+
+Convert Gitlab emojis to short codes with the ``emoji-gitlab`` locale::
+
+    $transliterator = EmojiTransliterator::create('emoji-gitlab');
+    $transliterator->transliterate('Breakfast with 🥝 or 🥛');
+    // => 'Breakfast with :kiwi: or :milk:'
+
+Convert Gitlab short codes to emojis with the ``gitlab-emoji`` locale::
+
+    $transliterator = EmojiTransliterator::create('gitlab-emoji');
+    $transliterator->transliterate('Breakfast with :kiwi: or :milk:');
+    // => 'Breakfast with 🥝 or 🥛'
+
 Slack Emoji Transliteration
 ...........................
 
@@ -693,7 +708,7 @@ with the slugger to transform any emojis into their textual representation::
     // $slug = 'un-chat-qui-sourit-chat-noir-et-un-tete-de-lion-vont-au-parc-national';
 
 If you want to use a specific locale for the emoji, or to use the short codes
-from GitHub or Slack, use the first argument of ``withEmoji()`` method::
+from GitHub, Gitlab or Slack, use the first argument of ``withEmoji()`` method::
 
     use Symfony\Component\String\Slugger\AsciiSlugger;
 

From 549de499fc334287e95c6227a07be92102c0ba4c Mon Sep 17 00:00:00 2001
From: Baptiste CONTRERAS <38988658+BaptisteContreras@users.noreply.github.com>
Date: Sat, 6 Apr 2024 20:45:27 +0200
Subject: [PATCH 213/747] [HttpFoundation] add documention for signed URI
 expiration

---
 routing.rst | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/routing.rst b/routing.rst
index 53ebe003e0a..0852883b9ee 100644
--- a/routing.rst
+++ b/routing.rst
@@ -2694,6 +2694,71 @@ service, which you can inject in your services or controllers::
         }
     }
 
+You can make the signed URI expire. To do so, you can pass a value to the `$expiration` argument
+of :phpmethod:`Symfony\\Component\\HttpFoundation\\UriSigner::sign`. This optional argument is `null` by default. You can
+specify an expiration date by several ways::
+
+    // src/Service/SomeService.php
+    namespace App\Service;
+
+    use Symfony\Component\HttpFoundation\UriSigner;
+
+    class SomeService
+    {
+        public function __construct(
+            private UriSigner $uriSigner,
+        ) {
+        }
+
+        public function someMethod(): void
+        {
+            // ...
+
+            // generate a URL yourself or get it somehow...
+            $url = 'https://example.com/foo/bar?sort=desc';
+
+            // sign the URL with an explicit expiration date
+            $signedUrl = $this->uriSigner->sign($url, new \DateTime('2050-01-01'));
+            // $signedUrl = 'https://example.com/foo/bar?sort=desc&_expiration=2524608000&_hash=e4a21b9'
+
+            // check the URL signature
+            $uriSignatureIsValid = $this->uriSigner->check($signedUrl);
+            // $uriSignatureIsValid = true
+
+            // if given a \DateInterval, it will be added from now to get the expiration date
+            $signedUrl = $this->uriSigner->sign($url, new \DateInterval('PT10S'));  // valid for 10 seconds from now
+            // $signedUrl = 'https://example.com/foo/bar?sort=desc&_expiration=1712414278&_hash=e4a21b9'
+
+            // check the URL signature
+            $uriSignatureIsValid = $this->uriSigner->check($signedUrl);
+            // $uriSignatureIsValid = true
+
+            sleep(30); // wait 30 seconds...
+
+            // the URL signature has expired
+            $uriSignatureIsValid = $this->uriSigner->check($signedUrl);
+            // $uriSignatureIsValid = false
+
+            // you can also use a timestamp in seconds
+            $signedUrl = $this->uriSigner->sign($url, 4070908800); // timestamp for the date 2099-01-01
+            // $signedUrl = 'https://example.com/foo/bar?sort=desc&_expiration=4070908800&_hash=e4a21b9'
+
+        }
+    }
+
+.. caution::
+
+    `null` means no expiration for the signed URI.
+
+.. note::
+
+    When making the URI expire, an `_expiration` query parameter is added to the URL and the expiration date is
+    converted into a timestamp
+
+.. versionadded:: 7.1
+
+    The possibility to add an expiration date for a signed URI was introduced in Symfony 7.1.
+
 Troubleshooting
 ---------------
 

From fa1934c08d505df970dafd840cb7604c9f4b9e46 Mon Sep 17 00:00:00 2001
From: Yonel Ceruto <yonel.ceruto@scnd.com>
Date: Sun, 7 Apr 2024 12:02:21 -0400
Subject: [PATCH 214/747] Documenting items type in the MapRequestPayload
 attribute

---
 controller.rst | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/controller.rst b/controller.rst
index c44f0dafdac..2edf6affb2f 100644
--- a/controller.rst
+++ b/controller.rst
@@ -555,6 +555,32 @@ if you want to map a nested array of specific DTOs::
         ) {}
     }
 
+Nevertheless, if you want to send the array of payloads directly like this:
+
+.. code-block:: json
+
+    [
+        {
+            "firstName": "John",
+            "lastName": "Smith",
+            "age": 28
+        },
+        {
+            "firstName": "Jane",
+            "lastName": "Doe",
+            "age": 30
+        }
+    ]
+
+Map the parameter as an array and configure the type of each element in the attribute::
+
+    public function dashboard(
+        #[MapRequestPayload(type: UserDTO::class)] array $users
+    ): Response
+    {
+        // ...
+    }
+
 Managing the Session
 --------------------
 

From bb68008b4bb3877e058b485958acb9f22a77c48f Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 5 Apr 2024 09:58:09 +0200
Subject: [PATCH 215/747] [Validator] Add a requireTld option to Url constraint

---
 reference/constraints/Url.rst | 111 ++++++++++++++++++++++++++++++++++
 1 file changed, 111 insertions(+)

diff --git a/reference/constraints/Url.rst b/reference/constraints/Url.rst
index 2c3420df7c6..b3a46d5aec4 100644
--- a/reference/constraints/Url.rst
+++ b/reference/constraints/Url.rst
@@ -307,3 +307,114 @@ also relative URLs that contain no protocol (e.g. ``//example.com``).
                 ]));
             }
         }
+
+``requireTld``
+~~~~~~~~~~~~~~
+
+**type**: ``boolean`` **default**: ``false``
+
+.. versionadded:: 7.1
+
+    The ``requiredTld`` option was introduced in Symfony 7.1.
+
+By default, URLs like ``https://aaa`` or ``https://foobar`` are considered valid
+because they are tecnically correct according to the `URL spec`_. If you set this option
+to ``true``, the host part of the URL will have to include a TLD (top-level domain
+name): e.g. ``https://example.com`` will be valid but ``https://example`` won't.
+
+.. 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).
+
+``tldMessage``
+~~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``This URL does not contain a TLD.``
+
+.. versionadded:: 7.1
+
+    The ``tldMessage`` option was introduced in Symfony 7.1.
+
+This message is shown if the ``requireTld`` option is set to ``true`` and the URL
+does not contain at least one TLD.
+
+You can use the following parameters in this message:
+
+===============  ==============================================================
+Parameter        Description
+===============  ==============================================================
+``{{ value }}``  The current (invalid) value
+``{{ label }}``  Corresponding form field label
+===============  ==============================================================
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Entity/Website.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+
+        class Website
+        {
+            #[Assert\Url(
+                requireTld: true,
+                tldMessage: 'Add at least one TLD to the {{ value }} URL.',
+            )]
+            protected string $homepageUrl;
+        }
+
+    .. code-block:: yaml
+
+        # config/validator/validation.yaml
+        App\Entity\Website:
+            properties:
+                homepageUrl:
+                    - Url:
+                        requireTld: true
+                        tldMessage: Add at least one TLD to the {{ value }} URL.
+
+    .. code-block:: xml
+
+        <!-- config/validator/validation.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
+
+            <class name="App\Entity\Website">
+                <property name="homepageUrl">
+                    <constraint name="Url">
+                        <option name="requireTld">true</option>
+                        <option name="tldMessage">Add at least one TLD to the {{ value }} URL.</option>
+                    </constraint>
+                </property>
+            </class>
+        </constraint-mapping>
+
+    .. code-block:: php
+
+        // src/Entity/Website.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+        use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+        class Website
+        {
+            // ...
+
+            public static function loadValidatorMetadata(ClassMetadata $metadata): void
+            {
+                $metadata->addPropertyConstraint('homepageUrl', new Assert\Url([
+                    'requireTld' => true,
+                    'tldMessage' => 'Add at least one TLD to the {{ value }} URL.',
+                ]));
+            }
+        }
+
+.. _`URL spec`: https://datatracker.ietf.org/doc/html/rfc1738
+.. _`list of official top-level domains`: https://en.wikipedia.org/wiki/List_of_Internet_top-level_domains

From f17331c882ab9cf9a870003929f58106bd0d14b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= <jerome@tamarelle.net>
Date: Tue, 9 Apr 2024 14:57:27 +0200
Subject: [PATCH 216/747] ServiceSubscriberTrait is deprecated and replaced by
 ServiceMethodsSubscriberTrait

---
 service_container/service_subscribers_locators.rst | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst
index 21a7ab295d2..d60b438694c 100644
--- a/service_container/service_subscribers_locators.rst
+++ b/service_container/service_subscribers_locators.rst
@@ -859,7 +859,7 @@ the following order:
 Service Subscriber Trait
 ------------------------
 
-The :class:`Symfony\\Contracts\\Service\\ServiceSubscriberTrait` provides an
+The :class:`Symfony\\Contracts\\Service\\ServiceMethodsSubscriberTrait` provides an
 implementation for :class:`Symfony\\Contracts\\Service\\ServiceSubscriberInterface`
 that looks through all methods in your class that are marked with the
 :class:`Symfony\\Contracts\\Service\\Attribute\\SubscribedService` attribute. It
@@ -873,12 +873,12 @@ services based on type-hinted helper methods::
     use Psr\Log\LoggerInterface;
     use Symfony\Component\Routing\RouterInterface;
     use Symfony\Contracts\Service\Attribute\SubscribedService;
+    use Symfony\Contracts\Service\ServiceMethodsSubscriberTrait;
     use Symfony\Contracts\Service\ServiceSubscriberInterface;
-    use Symfony\Contracts\Service\ServiceSubscriberTrait;
 
     class MyService implements ServiceSubscriberInterface
     {
-        use ServiceSubscriberTrait;
+        use ServiceMethodsSubscriberTrait;
 
         public function doSomething(): void
         {
@@ -935,12 +935,12 @@ and compose your services with them::
     // src/Service/MyService.php
     namespace App\Service;
 
+    use Symfony\Contracts\Service\ServiceMethodsSubscriberTrait;
     use Symfony\Contracts\Service\ServiceSubscriberInterface;
-    use Symfony\Contracts\Service\ServiceSubscriberTrait;
 
     class MyService implements ServiceSubscriberInterface
     {
-        use ServiceSubscriberTrait, LoggerAware, RouterAware;
+        use ServiceMethodsSubscriberTrait, LoggerAware, RouterAware;
 
         public function doSomething(): void
         {
@@ -977,12 +977,12 @@ Here's an example::
     use Symfony\Component\DependencyInjection\Attribute\Target;
     use Symfony\Component\Routing\RouterInterface;
     use Symfony\Contracts\Service\Attribute\SubscribedService;
+    use Symfony\Contracts\Service\ServiceMethodsSubscriberTrait;
     use Symfony\Contracts\Service\ServiceSubscriberInterface;
-    use Symfony\Contracts\Service\ServiceSubscriberTrait;
 
     class MyService implements ServiceSubscriberInterface
     {
-        use ServiceSubscriberTrait;
+        use ServiceMethodsSubscriberTrait;
 
         public function doSomething(): void
         {

From 078d6f909bfc3e45ca119b4ed5e6d0b50079db78 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 10 Apr 2024 12:46:19 +0200
Subject: [PATCH 217/747] Added the versionadded directive

---
 service_container/service_subscribers_locators.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst
index d60b438694c..25ebe97e7e7 100644
--- a/service_container/service_subscribers_locators.rst
+++ b/service_container/service_subscribers_locators.rst
@@ -899,6 +899,11 @@ services based on type-hinted helper methods::
         }
     }
 
+.. versionadded:: 7.1
+
+    The ``ServiceMethodsSubscriberTrait`` was introduced in Symfony 7.1.
+    In previous Symfony versions it was called ``ServiceSubscriberTrait``.
+
 This  allows you to create helper traits like RouterAware, LoggerAware, etc...
 and compose your services with them::
 

From 9bd321de567074972ce6f21cb3a92b98739e30e1 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 9 Apr 2024 17:59:15 +0200
Subject: [PATCH 218/747] [Clock] Document createFromTimestamp() method

---
 components/clock.rst | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/components/clock.rst b/components/clock.rst
index 45ec484eef5..933f7310d75 100644
--- a/components/clock.rst
+++ b/components/clock.rst
@@ -229,6 +229,21 @@ The constructor also allows setting a timezone or custom referenced date::
     $referenceDate = new \DateTimeImmutable();
     $relativeDate = new DatePoint('+1month', reference: $referenceDate);
 
+The ``DatePoint`` class also provides a named constructor to create dates from
+timestamps::
+
+    $dateOfFirstCommitOfSymfonyProject = DatePoint::createFromTimestamp(1129645656);
+    // equivalent to:
+    // $dateOfFirstCommitOfSymfonyProject = (new \DateTimeImmutable())->setTimestamp(1129645656);
+
+    // negative timestamps (for dates before January 1, 1970) and fractional timestamps
+    // (for high precision sub-second datetimes) are also supported
+    $dateOfFirstMoonLanding = DatePoint::createFromTimestamp(-14182940);
+
+.. versionadded:: 7.1
+
+    The ``createFromTimestamp()`` method was introduced in Symfony 7.1.
+
 .. note::
 
     In addition ``DatePoint`` offers stricter return types and provides consistent

From e801d38f755a6073bedcb1e64d8aafcd21de9abf Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 10 Apr 2024 15:30:58 +0200
Subject: [PATCH 219/747] Minor tweak

---
 components/clock.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/components/clock.rst b/components/clock.rst
index 933f7310d75..cdbbdd56e6b 100644
--- a/components/clock.rst
+++ b/components/clock.rst
@@ -232,11 +232,11 @@ The constructor also allows setting a timezone or custom referenced date::
 The ``DatePoint`` class also provides a named constructor to create dates from
 timestamps::
 
-    $dateOfFirstCommitOfSymfonyProject = DatePoint::createFromTimestamp(1129645656);
+    $dateOfFirstCommitToSymfonyProject = DatePoint::createFromTimestamp(1129645656);
     // equivalent to:
-    // $dateOfFirstCommitOfSymfonyProject = (new \DateTimeImmutable())->setTimestamp(1129645656);
+    // $dateOfFirstCommitToSymfonyProject = (new \DateTimeImmutable())->setTimestamp(1129645656);
 
-    // negative timestamps (for dates before January 1, 1970) and fractional timestamps
+    // negative timestamps (for dates before January 1, 1970) and float timestamps
     // (for high precision sub-second datetimes) are also supported
     $dateOfFirstMoonLanding = DatePoint::createFromTimestamp(-14182940);
 

From f9c53b97e032e7c78c6f02d5e333d1b2702bbb35 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Thu, 11 Apr 2024 11:18:33 +0200
Subject: [PATCH 220/747] [Mailer] Add the `allowed_recipients` option

---
 mailer.rst | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/mailer.rst b/mailer.rst
index f32f0ff0cfc..2ce97859b11 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -1852,6 +1852,75 @@ a specific address, instead of the *real* address:
             ;
         };
 
+You may also go even further by restricting the recipient to a specific
+address, except for some specific ones. This can be done by using the
+``allowed_recipients`` option:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/mailer.yaml
+        when@dev:
+            framework:
+                mailer:
+                    envelope:
+                        recipients: ['youremail@example.com']
+                        allowed_recipients:
+                            - 'interal@example.com'
+                            # you can also use regular expression to define allowed recipients
+                            - 'internal-.*@example.(com|fr)'
+
+    .. code-block:: xml
+
+        <!-- config/packages/mailer.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <!-- ... -->
+            <framework:config>
+                <framework:mailer>
+                    <framework:envelope>
+                        <framework:recipient>youremail@example.com</framework:recipient>
+                        <framework:allowed-recipient>internal@example.com</framework:allowed-recipient>
+                        <!-- you can also use regular expression to define allowed recipients -->
+                        <framework:allowed-recipient>internal-.*@example.(com|fr)</framework:allowed-recipient>
+                    </framework:envelope>
+                </framework:mailer>
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/mailer.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            // ...
+            $framework->mailer()
+                ->envelope()
+                    ->recipients(['youremail@example.com'])
+                    ->allowedRecipients([
+                        'internal@example.com',
+                        // you can also use regular expression to define allowed recipients
+                        'internal-.*@example.(com|fr)',
+                    ])
+            ;
+        };
+
+With this configuration, all emails will be sent to ``youremail@example.com``,
+except for those sent to ``internal@example.com``, which will receive emails as
+usual.
+
+.. versionadded:: 7.1
+
+    The ``allowed_recipients`` option was introduced in Symfony 7.1.
+
 Write a Functional Test
 ~~~~~~~~~~~~~~~~~~~~~~~
 

From f79518512854c71097b15784caf4fd674a6419c7 Mon Sep 17 00:00:00 2001
From: Florent Morselli <florent.morselli@spomky-labs.com>
Date: Thu, 11 Apr 2024 19:28:08 +0200
Subject: [PATCH 221/747] Update OidcTokenHandler dependencies and
 configuration

This commit replaces the individual jwt packages previously needed by 'OidcTokenHandler' with the `web-token/jwt-library`. Configuration changes have been made to support multiple signing algorithms and a keyset instead of a single key. These changes provide more flexibility and reliability for token handling and verification.
---
 security/access_token.rst | 35 ++++++++++++++++++-----------------
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/security/access_token.rst b/security/access_token.rst
index 5057e243c25..593c6404c7a 100644
--- a/security/access_token.rst
+++ b/security/access_token.rst
@@ -537,15 +537,12 @@ claims. To create your own user object from the claims, you must
 2) Configure the OidcTokenHandler
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The ``OidcTokenHandler`` requires ``web-token/jwt-signature``,
-``web-token/jwt-checker`` and ``web-token/jwt-signature-algorithm-ecdsa``
-packages. If you haven't installed them yet, run these commands:
+The ``OidcTokenHandler`` requires the package ``web-token/jwt-library``.
+If you haven't installed it yet, run this command:
 
 .. code-block:: terminal
 
-    $ composer require web-token/jwt-signature
-    $ composer require web-token/jwt-checker
-    $ composer require web-token/jwt-signature-algorithm-ecdsa
+    $ composer require web-token/jwt-library
 
 Symfony provides a generic ``OidcTokenHandler`` to decode your token, validate
 it and retrieve the user info from it:
@@ -561,10 +558,10 @@ it and retrieve the user info from it:
                     access_token:
                         token_handler:
                             oidc:
-                                # Algorithm used to sign the JWS
-                                algorithm: 'ES256'
+                                # Algorithms used to sign the JWS
+                                algorithms: ['ES256', 'RS256']
                                 # A JSON-encoded JWK
-                                key: '{"kty":"...","k":"..."}'
+                                keyset: '{"keys":[{"kty":"...","k":"..."}]}'
                                 # Audience (`aud` claim): required for validation purpose
                                 audience: 'api-example'
                                 # Issuers (`iss` claim): required for validation purpose
@@ -589,8 +586,10 @@ it and retrieve the user info from it:
                             <!-- Algorithm used to sign the JWS -->
                             <!-- A JSON-encoded JWK -->
                             <!-- Audience (`aud` claim): required for validation purpose -->
-                            <oidc algorithm="ES256" key="{'kty':'...','k':'...'}" audience="api-example">
+                            <oidc keyset="{'keys':[{'kty':'...','k':'...'}]}" audience="api-example">
                                 <!-- Issuers (`iss` claim): required for validation purpose -->
+                                <algorithm>ES256</algorithm>
+                                <algorithm>RS256</algorithm>
                                 <issuer>https://oidc.example.com</issuer>
                             </oidc>
                         </token-handler>
@@ -610,9 +609,9 @@ it and retrieve the user info from it:
                     ->tokenHandler()
                         ->oidc()
                             // Algorithm used to sign the JWS
-                            ->algorithm('ES256')
+                            ->algorithms(['ES256', 'RS256'])
                             // A JSON-encoded JWK
-                            ->key('{"kty":"...","k":"..."}')
+                            ->keyset('{"keys":[{"kty":"...","k":"..."}]}')
                             // Audience (`aud` claim): required for validation purpose
                             ->audience('api-example')
                             // Issuers (`iss` claim): required for validation purpose
@@ -636,8 +635,8 @@ configuration:
                         token_handler:
                             oidc:
                                 claim: email
-                                algorithm: 'ES256'
-                                key: '{"kty":"...","k":"..."}'
+                                algorithms: ['ES256', 'RS256']
+                                keyset: '{"keys":[{"kty":"...","k":"..."}]}'
                                 audience: 'api-example'
                                 issuers: ['https://oidc.example.com']
 
@@ -657,7 +656,9 @@ configuration:
                 <firewall name="main">
                     <access-token>
                         <token-handler>
-                            <oidc claim="email" algorithm="ES256" key="{'kty':'...','k':'...'}" audience="api-example">
+                            <oidc claim="email" keyset="{'keys':[{'kty':'...','k':'...'}]}" audience="api-example">
+                                <algorithm>ES256</algorithm>
+                                <algorithm>RS256</algorithm>
                                 <issuer>https://oidc.example.com</issuer>
                             </oidc>
                         </token-handler>
@@ -677,8 +678,8 @@ configuration:
                     ->tokenHandler()
                         ->oidc()
                             ->claim('email')
-                            ->algorithm('ES256')
-                            ->key('{"kty":"...","k":"..."}')
+                            ->algorithms(['ES256', 'RS256'])
+                            ->keyset('{"keys":[{"kty":"...","k":"..."}]}')
                             ->audience('api-example')
                             ->issuers(['https://oidc.example.com'])
             ;

From 7de0684b22c26bd4494eba8daa64eb4f097cfeef Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 12 Apr 2024 08:57:34 +0200
Subject: [PATCH 222/747] Minor reword

---
 mailer.rst | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index 2ce97859b11..643702bdee1 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -1852,9 +1852,9 @@ a specific address, instead of the *real* address:
             ;
         };
 
-You may also go even further by restricting the recipient to a specific
-address, except for some specific ones. This can be done by using the
-``allowed_recipients`` option:
+Use the ``allowed_recipients`` option to specify exceptions to the behavior defined
+in the ``recipients`` option; allowing emails directed to these specific recipients
+to maintain their original destination:
 
 .. configuration-block::
 
@@ -1867,7 +1867,7 @@ address, except for some specific ones. This can be done by using the
                     envelope:
                         recipients: ['youremail@example.com']
                         allowed_recipients:
-                            - 'interal@example.com'
+                            - 'internal@example.com'
                             # you can also use regular expression to define allowed recipients
                             - 'internal-.*@example.(com|fr)'
 
@@ -1914,8 +1914,8 @@ address, except for some specific ones. This can be done by using the
         };
 
 With this configuration, all emails will be sent to ``youremail@example.com``,
-except for those sent to ``internal@example.com``, which will receive emails as
-usual.
+except for those sent to ``internal@example.com``, ``internal-monitoring@example.fr``,
+etc., which will receive emails as usual.
 
 .. versionadded:: 7.1
 

From 75ab793bcc1ad27b0c47f57c5f7d4f1b0cd30ec1 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 12 Apr 2024 11:50:48 +0200
Subject: [PATCH 223/747] Minor rewords

---
 routing.rst | 36 +++++++++---------------------------
 1 file changed, 9 insertions(+), 27 deletions(-)

diff --git a/routing.rst b/routing.rst
index 0852883b9ee..790ae314516 100644
--- a/routing.rst
+++ b/routing.rst
@@ -2694,9 +2694,10 @@ service, which you can inject in your services or controllers::
         }
     }
 
-You can make the signed URI expire. To do so, you can pass a value to the `$expiration` argument
-of :phpmethod:`Symfony\\Component\\HttpFoundation\\UriSigner::sign`. This optional argument is `null` by default. You can
-specify an expiration date by several ways::
+For security reasons, it's common to make signed URIs expire after some time
+(e.g. when using them to reset user credentials). By default, signed URIs don't
+expire, but you can define an expiration date/time using the ``$expiration``
+argument of :phpmethod:`Symfony\\Component\\HttpFoundation\\UriSigner::sign`::
 
     // src/Service/SomeService.php
     namespace App\Service;
@@ -2718,46 +2719,27 @@ specify an expiration date by several ways::
             $url = 'https://example.com/foo/bar?sort=desc';
 
             // sign the URL with an explicit expiration date
-            $signedUrl = $this->uriSigner->sign($url, new \DateTime('2050-01-01'));
+            $signedUrl = $this->uriSigner->sign($url, new \DateTimeImmutable('2050-01-01'));
             // $signedUrl = 'https://example.com/foo/bar?sort=desc&_expiration=2524608000&_hash=e4a21b9'
 
-            // check the URL signature
-            $uriSignatureIsValid = $this->uriSigner->check($signedUrl);
-            // $uriSignatureIsValid = true
-
-            // if given a \DateInterval, it will be added from now to get the expiration date
+            // if you pass a \DateInterval, it will be added from now to get the expiration date
             $signedUrl = $this->uriSigner->sign($url, new \DateInterval('PT10S'));  // valid for 10 seconds from now
             // $signedUrl = 'https://example.com/foo/bar?sort=desc&_expiration=1712414278&_hash=e4a21b9'
 
-            // check the URL signature
-            $uriSignatureIsValid = $this->uriSigner->check($signedUrl);
-            // $uriSignatureIsValid = true
-
-            sleep(30); // wait 30 seconds...
-
-            // the URL signature has expired
-            $uriSignatureIsValid = $this->uriSigner->check($signedUrl);
-            // $uriSignatureIsValid = false
-
             // you can also use a timestamp in seconds
             $signedUrl = $this->uriSigner->sign($url, 4070908800); // timestamp for the date 2099-01-01
             // $signedUrl = 'https://example.com/foo/bar?sort=desc&_expiration=4070908800&_hash=e4a21b9'
-
         }
     }
 
-.. caution::
-
-    `null` means no expiration for the signed URI.
-
 .. note::
 
-    When making the URI expire, an `_expiration` query parameter is added to the URL and the expiration date is
-    converted into a timestamp
+    The expiration date/time is included in the signed URIs as a timestamp via
+    the ``_expiration`` query parameter.
 
 .. versionadded:: 7.1
 
-    The possibility to add an expiration date for a signed URI was introduced in Symfony 7.1.
+    The feature to add an expiration date for a signed URI was introduced in Symfony 7.1.
 
 Troubleshooting
 ---------------

From d0fd14b4c4ad1bebad99d6d4594d5ef0d2af7729 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 12 Apr 2024 17:25:03 +0200
Subject: [PATCH 224/747] Add a versionadded directive

---
 translation.rst | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/translation.rst b/translation.rst
index 3320ce9ee37..eb16fbee1bb 100644
--- a/translation.rst
+++ b/translation.rst
@@ -979,8 +979,14 @@ preferences. This is achieved with the ``getPreferredLanguage()`` method of the
 
 Symfony finds the best possible language based on the locales passed as argument
 and the value of the ``Accept-Language`` HTTP header. If it can't find a perfect
-match between them, this method returns the first locale passed as argument
-(that's why the order of the passed locales is important).
+match between them, Symfony will try to find a partial match based on the language
+(e.g. ``fr_CA`` would match ``fr_Latn_CH`` because their language is the same).
+If there's no perfect or partial match, this method returns the first locale passed
+as argument (that's why the order of the passed locales is important).
+
+.. versionadded:: 7.1
+
+    The feature to match lcoales partially was introduced in Symfony 7.1.
 
 .. _translation-fallback:
 

From 6ac1b818e7697eff318fd95ad16409dd22e78994 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 12 Apr 2024 17:45:42 +0200
Subject: [PATCH 225/747] Fix typo

---
 translation.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/translation.rst b/translation.rst
index eb16fbee1bb..891f00845cb 100644
--- a/translation.rst
+++ b/translation.rst
@@ -986,7 +986,7 @@ as argument (that's why the order of the passed locales is important).
 
 .. versionadded:: 7.1
 
-    The feature to match lcoales partially was introduced in Symfony 7.1.
+    The feature to match locales partially was introduced in Symfony 7.1.
 
 .. _translation-fallback:
 

From 0ed185ac3443c8718127e4dbd0ac4588112abd20 Mon Sep 17 00:00:00 2001
From: Ninos Ego <me@ninosego.de>
Date: Fri, 12 Apr 2024 18:05:28 +0200
Subject: [PATCH 226/747] [Validator] Add support for types (`ALL*`, `LOCAL_*`,
 `UNIVERSAL_*`, `UNICAST_*`, `MULTICAST_*`, `BROADCAST`) in `MacAddress`
 constraint

---
 reference/constraints/MacAddress.rst | 29 ++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/reference/constraints/MacAddress.rst b/reference/constraints/MacAddress.rst
index 8055b53ff4a..93fe8142fc4 100644
--- a/reference/constraints/MacAddress.rst
+++ b/reference/constraints/MacAddress.rst
@@ -103,4 +103,33 @@ Parameter            Description
 
 .. include:: /reference/constraints/_payload-option.rst.inc
 
+.. _reference-constraint-mac-address-type:
+
+``type``
+~~~~~~~~
+
+**type**: ``string`` **default**: ``all``
+
+This determines exactly *how* the MAC address is validated. This option defines a
+lot of different possible values based on the type of MAC address that you want to allow/deny:
+
+================================  ==============================================================
+Parameter                         Description
+================================  ==============================================================
+``all``                           All
+``all_no_broadcast``              All except broadcast
+``local_all``                     Only local
+``local_no_broadcast``            Only local except broadcast
+``local_unicast``                 Only local and unicast
+``local_multicast``               Only local and multicast
+``local_multicast_no_broadcast``  Only local and multicast except broadcast
+``universal_all``                 Only universal
+``universal_unicast``             Only universal and unicast
+``universal_multicast``           Only universal and multicast
+``unicast_all``                   Only unicast
+``multicast_all``                 Only multicast
+``multicast_no_broadcast``        Only multicast except broadcast
+``broadcast``                     Only broadcast
+===============  ==============================================================
+
 .. _`MAC address`: https://en.wikipedia.org/wiki/MAC_address

From babae18a11a2c3e84de9d0448cbdb9def239b438 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 15 Apr 2024 09:17:57 +0200
Subject: [PATCH 227/747] Tweaks

---
 reference/constraints/MacAddress.rst | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/reference/constraints/MacAddress.rst b/reference/constraints/MacAddress.rst
index 93fe8142fc4..2958af49874 100644
--- a/reference/constraints/MacAddress.rst
+++ b/reference/constraints/MacAddress.rst
@@ -110,26 +110,29 @@ Parameter            Description
 
 **type**: ``string`` **default**: ``all``
 
-This determines exactly *how* the MAC address is validated. This option defines a
-lot of different possible values based on the type of MAC address that you want to allow/deny:
+.. versionadded:: 7.1
+
+    The ``type`` option was introduced in Symfony 7.1.
 
-================================  ==============================================================
-Parameter                         Description
-================================  ==============================================================
+This option defines the kind of MAC addresses that are allowed. There are a lot
+of different possible values based on your needs:
+
+================================  =========================================
+Parameter                         Allowed MAC addresses
+================================  =========================================
 ``all``                           All
 ``all_no_broadcast``              All except broadcast
+``broadcast``                     Only broadcast
 ``local_all``                     Only local
+``local_multicast_no_broadcast``  Only local and multicast except broadcast
+``local_multicast``               Only local and multicast
 ``local_no_broadcast``            Only local except broadcast
 ``local_unicast``                 Only local and unicast
-``local_multicast``               Only local and multicast
-``local_multicast_no_broadcast``  Only local and multicast except broadcast
-``universal_all``                 Only universal
-``universal_unicast``             Only universal and unicast
-``universal_multicast``           Only universal and multicast
-``unicast_all``                   Only unicast
 ``multicast_all``                 Only multicast
 ``multicast_no_broadcast``        Only multicast except broadcast
-``broadcast``                     Only broadcast
-===============  ==============================================================
+``unicast_all``                   Only unicast
+``universal_all``                 Only universal
+``universal_multicast``           Only universal and multicast
+================================  =========================================
 
 .. _`MAC address`: https://en.wikipedia.org/wiki/MAC_address

From 25c5adfcbb2c68ebe8261643afcebf53464206ea Mon Sep 17 00:00:00 2001
From: Yonel Ceruto <yonel.ceruto@scnd.com>
Date: Wed, 3 Apr 2024 19:12:01 -0400
Subject: [PATCH 228/747] Updating prepend extension capabilities

---
 bundles/prepend_extension.rst | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/bundles/prepend_extension.rst b/bundles/prepend_extension.rst
index 2a5736c440e..807c7f18caf 100644
--- a/bundles/prepend_extension.rst
+++ b/bundles/prepend_extension.rst
@@ -171,6 +171,9 @@ method::
             $containerBuilder->prependExtensionConfig('framework', [
                 'cache' => ['prefix_seed' => 'foo/bar'],
             ]);
+
+            // prepend config from a file
+            $containerConfigurator->import('../config/packages/cache.php');
         }
     }
 
@@ -178,6 +181,12 @@ method::
 
     The ``prependExtension()`` method, like ``prepend()``, is called only at compile time.
 
+.. deprecated:: 7.1
+
+    The :method:`Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator::import`
+    method behavior was modified in Symfony 7.1 to prepend config instead of appending. This behavior change only
+    affects to the ``prependExtension()`` method.
+
 Alternatively, you can use the ``prepend`` parameter of the
 :method:`Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator::extension`
 method::

From a58dccf088719da4dceedc49dab3d5c18b2701b3 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 15 Apr 2024 17:01:53 +0200
Subject: [PATCH 229/747] Reword

---
 console/input.rst | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/console/input.rst b/console/input.rst
index f889926be59..6e7fc85a055 100644
--- a/console/input.rst
+++ b/console/input.rst
@@ -314,29 +314,34 @@ The above code can be simplified as follows because ``false !== null``::
 Fetching The Raw Command Input
 ------------------------------
 
-Sometimes, you may need to fetch the raw input that was passed to the command.
-This is useful when you need to parse the input yourself or when you need to
-pass the input to another command without having to worry about the number
-of arguments or options defined in your own command. This can be achieved
-thanks to the
-:method:`Symfony\\Component\\Console\\Input\\ArgvInput::getRawTokens` method::
+Symfony provides a :method:`Symfony\\Component\\Console\\Input\\ArgvInput::getRawTokens`
+method to fetch the raw input that was passed to the command. This is useful if
+you want to parse the input yourself or when you need to pass the input to another
+command without having to worry about the number of arguments or options::
 
     // ...
     use Symfony\Component\Process\Process;
 
     protected function execute(InputInterface $input, OutputInterface $output): int
     {
-        // pass the raw input of your command to the "ls" command
-        $process = new Process(['ls', ...$input->getRawTokens(true)]);
+        // if this command was run as:
+        // php bin/console app:my-command foo --bar --baz=3 --qux=value1 --qux=value2
+
+        $tokens = $input->getRawTokens();
+        // $tokens = ['app:my-command', 'foo', '--bar', '--baz=3', '--qux=value1', '--qux=value2'];
+
+        // pass true as argument to not include the original command name
+        $tokens = $input->getRawTokens(true);
+        // $tokens = ['foo', '--bar', '--baz=3', '--qux=value1', '--qux=value2'];
+
+        // pass the raw input to any other command (from Symfony or the operating system)
+        $process = new Process(['app:other-command', ...$input->getRawTokens(true)]);
         $process->setTty(true);
         $process->mustRun();
 
         // ...
     }
 
-You can include the current command name in the raw tokens by passing ``true``
-to the ``getRawTokens`` method only parameter.
-
 .. versionadded:: 7.1
 
     The :method:`Symfony\\Component\\Console\\Input\\ArgvInput::getRawTokens`

From 4937afbab404e8fdeaa51d9cba2d7eaff2edc67d Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 15 Apr 2024 17:57:32 +0200
Subject: [PATCH 230/747] Minor reword

---
 bundles/prepend_extension.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/bundles/prepend_extension.rst b/bundles/prepend_extension.rst
index 807c7f18caf..e4099d9f81a 100644
--- a/bundles/prepend_extension.rst
+++ b/bundles/prepend_extension.rst
@@ -181,11 +181,11 @@ method::
 
     The ``prependExtension()`` method, like ``prepend()``, is called only at compile time.
 
-.. deprecated:: 7.1
+.. versionadded:: 7.1
 
-    The :method:`Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator::import`
-    method behavior was modified in Symfony 7.1 to prepend config instead of appending. This behavior change only
-    affects to the ``prependExtension()`` method.
+    Starting from Symfony 7.1, calling the :method:`Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator::import`
+    method inside ``prependExtension()`` will prepend the given configuration.
+    In previous Symfony versions, this method appended the configuration.
 
 Alternatively, you can use the ``prepend`` parameter of the
 :method:`Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator::extension`

From f1793555e2e68d4b7754f5022487753a3621a8fa Mon Sep 17 00:00:00 2001
From: Andrey Lebedev <andrew.lebedev@gmail.com>
Date: Wed, 20 Mar 2024 21:37:29 +0400
Subject: [PATCH 231/747] [Notifier] LOX24 SMS Gateway Notifier

---
 notifier.rst | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/notifier.rst b/notifier.rst
index 6bf3ab71c48..c9cf3068d1c 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -74,6 +74,7 @@ Service             Package                                DSN
 `Iqsms`_            ``symfony/iqsms-notifier``             ``iqsms://LOGIN:PASSWORD@default?from=FROM``
 `KazInfoTeh`_       ``symfony/kaz-info-teh-notifier``      ``kaz-info-teh://USERNAME:PASSWORD@default?sender=FROM``
 `LightSms`_         ``symfony/light-sms-notifier``         ``lightsms://LOGIN:TOKEN@default?from=PHONE``
+`LOX24`_            ``symfony/lox24-notifier``             ``lox24://USER:TOKEN@default?from=FROM``
 `Mailjet`_          ``symfony/mailjet-notifier``           ``mailjet://TOKEN@default?from=FROM``
 `MessageBird`_      ``symfony/message-bird-notifier``      ``messagebird://TOKEN@default?from=FROM``
 `MessageMedia`_     ``symfony/message-media-notifier``     ``messagemedia://API_KEY:API_SECRET@default?from=FROM``
@@ -115,7 +116,7 @@ Service             Package                                DSN
 
 .. versionadded:: 7.1
 
-    The `SmsSluzba`_ and  `SMSense`_ integrations were introduced in Symfony 7.1.
+    The `SmsSluzba`_, `SMSense`_  and `LOX24`_ integrations were introduced in Symfony 7.1.
 
 .. deprecated:: 7.1
 
@@ -1005,6 +1006,7 @@ is dispatched. Listeners receive a
 .. _`LINE Notify`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/LineNotify/README.md
 .. _`LightSms`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/LightSms/README.md
 .. _`LinkedIn`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/LinkedIn/README.md
+.. _`LOX24`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Lox24/README.md
 .. _`Mailjet`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Mailjet/README.md
 .. _`Mastodon`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Mastodon/README.md
 .. _`Mattermost`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Mattermost/README.md

From 885d65db770ec0f72b77d5f6f2169d8f43774314 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 16 Apr 2024 16:06:54 +0200
Subject: [PATCH 232/747] Minor tweak

---
 controller.rst | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/controller.rst b/controller.rst
index 2edf6affb2f..90277e07b76 100644
--- a/controller.rst
+++ b/controller.rst
@@ -555,7 +555,8 @@ if you want to map a nested array of specific DTOs::
         ) {}
     }
 
-Nevertheless, if you want to send the array of payloads directly like this:
+Instead of returning an array of DTO objects, you can tell Symfony to transform
+each DTO object into an array and return something like this:
 
 .. code-block:: json
 
@@ -572,7 +573,8 @@ Nevertheless, if you want to send the array of payloads directly like this:
         }
     ]
 
-Map the parameter as an array and configure the type of each element in the attribute::
+To do so, map the parameter as an array and configure the type of each element
+using the ``type`` option of the attribute::
 
     public function dashboard(
         #[MapRequestPayload(type: UserDTO::class)] array $users
@@ -581,6 +583,10 @@ Map the parameter as an array and configure the type of each element in the attr
         // ...
     }
 
+.. versionadded:: 7.1
+
+    The ``type`` option of ``#[MapRequestPayload]`` was introduced in Symfony 7.1.
+
 Managing the Session
 --------------------
 

From be50a3c6688a941325699568dad333e39accc669 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20Andr=C3=A9?= <smn.andre@gmail.com>
Date: Wed, 17 Apr 2024 12:29:10 +0200
Subject: [PATCH 233/747] Fix Explicite nullable types (7.0)

---
 testing.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/testing.rst b/testing.rst
index ee3a6c50191..0dfa5212217 100644
--- a/testing.rst
+++ b/testing.rst
@@ -1082,10 +1082,10 @@ Mailer Assertions
 Notifier Assertions
 ...................
 
-``assertNotificationCount(int $count, string $transportName = null, string $message = '')``
+``assertNotificationCount(int $count, ?string $transportName = null, string $message = '')``
     Asserts that the given number of notifications has been created
     (in total or for the given transport).
-``assertQueuedNotificationCount(int $count, string $transportName = null, string $message = '')``
+``assertQueuedNotificationCount(int $count, ?string $transportName = null, string $message = '')``
     Asserts that the given number of notifications are queued
     (in total or for the given transport).
 ``assertNotificationIsQueued(MessageEvent $event, string $message = '')``
@@ -1113,7 +1113,7 @@ HttpClient Assertions
     For all the following assertions, ``$client->enableProfiler()`` must be
     called before the code that will trigger HTTP request(s).
 
-``assertHttpClientRequest(string $expectedUrl, string $expectedMethod = 'GET', string|array $expectedBody = null, array $expectedHeaders = [], string $httpClientId = 'http_client')``
+``assertHttpClientRequest(string $expectedUrl, string $expectedMethod = 'GET', string|array|null $expectedBody = null, array $expectedHeaders = [], string $httpClientId = 'http_client')``
     Asserts that the given URL has been called using, if specified,
     the given method body and headers. By default it will check on the HttpClient,
     but you can also pass a specific HttpClient ID.

From f7225d9ef76dcc592dd124d373e3e08eb301ed48 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Fri, 19 Apr 2024 16:09:45 +0200
Subject: [PATCH 234/747] fix typo

---
 components/intl.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/intl.rst b/components/intl.rst
index d18ac21b10a..008d9161fd7 100644
--- a/components/intl.rst
+++ b/components/intl.rst
@@ -389,7 +389,7 @@ Symfony provides utilities to translate emojis into their textual representation
 in all languages. Read the documentation on :ref:`working with emojis in strings <string-emoji-transliteration>`
 to learn more about this feature.
 
-Disk space
+Disk Space
 ----------
 
 If you need to save disk space (e.g. because you deploy to some service with tight size

From e98c6f14159186418ba2320450a25a2d4fbde33b Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 22 Apr 2024 11:00:22 +0200
Subject: [PATCH 235/747] [Process] Mention `Process::setIgnoredSignals`

---
 components/process.rst | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/components/process.rst b/components/process.rst
index c4db5c18a9c..9502665dde1 100644
--- a/components/process.rst
+++ b/components/process.rst
@@ -511,6 +511,20 @@ When running a program asynchronously, you can send it POSIX signals with the
     // will send a SIGKILL to the process
     $process->signal(SIGKILL);
 
+You can make the process ignore signals by using the
+:method:`Symfony\\Component\\Process\\Process::setIgnoredSignals`
+method. The given signals won't be propagated to the child process::
+
+    use Symfony\Component\Process\Process;
+
+    $process = new Process(['find', '/', '-name', 'rabbit']);
+    $process->setIgnoredSignals([SIGKILL, SIGUSR1]);
+
+.. versionadded:: 7.1
+
+    The :method:`Symfony\\Component\\Process\\Process::setIgnoredSignals`
+    method was introduced in Symfony 7.1.
+
 Process Pid
 -----------
 

From 6e19233cf00ff3ae35c781dfdac0726faf159e75 Mon Sep 17 00:00:00 2001
From: Matthias Schmidt <matthias@mttsch.dev>
Date: Mon, 22 Apr 2024 19:21:13 +0200
Subject: [PATCH 236/747] [DependencyInjection] Add `#[AutowireMethodOf]`
 attribute

Co-Authored-By: Oskar Stark <oskarstark@googlemail.com>
---
 reference/attributes.rst         |  1 +
 service_container/autowiring.rst | 30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/reference/attributes.rst b/reference/attributes.rst
index 015b8751834..a1e8532c347 100644
--- a/reference/attributes.rst
+++ b/reference/attributes.rst
@@ -35,6 +35,7 @@ Dependency Injection
 * :doc:`AutowireDecorated </service_container/service_decoration>`
 * :doc:`AutowireIterator <service-locator_autowire-iterator>`
 * :ref:`AutowireLocator <service-locator_autowire-locator>`
+* :ref:`AutowireMethodOf <autowiring_closures>`
 * :ref:`AutowireServiceClosure <autowiring_closures>`
 * :ref:`Exclude <service-psr4-loader>`
 * :ref:`Lazy <lazy-services_configuration>`
diff --git a/service_container/autowiring.rst b/service_container/autowiring.rst
index 3c7a2eba52b..8b2b1c4d51d 100644
--- a/service_container/autowiring.rst
+++ b/service_container/autowiring.rst
@@ -737,6 +737,36 @@ attribute. By doing so, the callable will automatically be lazy, which means
 that the encapsulated service will be instantiated **only** at the
 closure's first call.
 
+:class:`Symfony\Component\DependencyInjection\Attribute\\AutowireMethodOf`
+provides a simpler way of specifying the name of the service method by using
+the property name as method name::
+
+    // src/Service/MessageGenerator.php
+    namespace App\Service;
+
+    use Symfony\Component\DependencyInjection\Attribute\AutowireMethodOf;
+
+    class MessageGenerator
+    {
+        public function __construct(
+            #[AutowireMethodOf('third_party.remote_message_formatter')]
+            private \Closure $format,
+        ) {
+        }
+
+        public function generate(string $message): void
+        {
+            $formattedMessage = ($this->format)($message);
+
+            // ...
+        }
+    }
+
+.. versionadded:: 7.1
+
+    :class:`Symfony\Component\DependencyInjection\Attribute\\AutowireMethodOf`
+    was introduced in Symfony 7.1.
+
 .. _autowiring-calls:
 
 Autowiring other Methods (e.g. Setters and Public Typed Properties)

From c7c9182ec30c39536203d1a7953b36a81bb1e7ce Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Mon, 22 Apr 2024 20:37:33 +0200
Subject: [PATCH 237/747] -

---
 service_container/autowiring.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/service_container/autowiring.rst b/service_container/autowiring.rst
index f3a32c01ea0..594e5f584f8 100644
--- a/service_container/autowiring.rst
+++ b/service_container/autowiring.rst
@@ -765,8 +765,8 @@ the property name as method name::
 
 .. versionadded:: 7.1
 
-    :class:`Symfony\Component\DependencyInjection\Attribute\\AutowireMethodOf`
-    was introduced in Symfony 7.1.
+    The :class:`Symfony\Component\DependencyInjection\Attribute\\AutowireMethodOf`
+    attribute was introduced in Symfony 7.1.
 
 .. _autowiring-calls:
 

From 20759594a59d907a06c0489f21ea300cf67ec4a8 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Mon, 22 Apr 2024 20:40:25 +0200
Subject: [PATCH 238/747] -

---
 service_container/autowiring.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/service_container/autowiring.rst b/service_container/autowiring.rst
index f89cfdbdc32..8ccde353fe9 100644
--- a/service_container/autowiring.rst
+++ b/service_container/autowiring.rst
@@ -738,9 +738,9 @@ attribute. By doing so, the callable will automatically be lazy, which means
 that the encapsulated service will be instantiated **only** at the
 closure's first call.
 
-:class:`Symfony\Component\DependencyInjection\Attribute\\AutowireMethodOf`
-provides a simpler way of specifying the name of the service method by using
-the property name as method name::
+The :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireMethodOf`
+attribute provides a simpler way of specifying the name of the service method
+by using the property name as method name::
 
     // src/Service/MessageGenerator.php
     namespace App\Service;

From 43355162a8cce5c794299e6d359a8a436929c067 Mon Sep 17 00:00:00 2001
From: Rene Lima <renedelima@gmail.com>
Date: Fri, 19 Apr 2024 20:28:09 +0200
Subject: [PATCH 239/747] Add documentation for #[MapUploadedFile] attribute

---
 controller.rst           | 93 ++++++++++++++++++++++++++++++++++++++++
 reference/attributes.rst |  1 +
 2 files changed, 94 insertions(+)

diff --git a/controller.rst b/controller.rst
index 90277e07b76..f0cac7b2350 100644
--- a/controller.rst
+++ b/controller.rst
@@ -587,6 +587,99 @@ using the ``type`` option of the attribute::
 
     The ``type`` option of ``#[MapRequestPayload]`` was introduced in Symfony 7.1.
 
+.. _controller_map-uploaded-file:
+
+Mapping Uploaded File
+~~~~~~~~~~~~~~~~~~~~~
+
+You can map ``UploadedFile``s to the controller arguments and optionally bind ``Constraints`` to them.
+The argument resolver fetches the ``UploadedFile`` based on the argument name.
+
+::
+
+    namespace App\Controller;
+
+    use Symfony\Component\HttpFoundation\File\UploadedFile;
+    use Symfony\Component\HttpFoundation\Response;
+    use Symfony\Component\HttpKernel\Attribute\MapUploadedFile;
+    use Symfony\Component\Routing\Attribute\Route;
+    use Symfony\Component\Validator\Constraints as Assert;
+
+    #[Route('/user/picture', methods: ['PUT'])]
+    class ChangeUserPictureController
+    {
+        public function _invoke(
+            #[MapUploadedFile([
+                new Assert\File(mimeTypes: ['image/png', 'image/jpeg']),
+                new Assert\Image(maxWidth: 3840, maxHeight: 2160)
+            ])]
+            UploadedFile $picture
+        ): Response {
+            // ...
+        }
+    }
+
+.. tip::
+
+    The bound ``Constraints`` are performed before injecting the ``UploadedFile`` into the controller argument.
+    When a constraint violation is detected an ``HTTPException`` is thrown and the controller's
+    action is not executed.
+
+Mapping ``UploadedFile``s with no custom settings.
+
+.. code-block:: php-attributes
+
+    #[MapUploadedFile]
+    UploadedFile $document
+
+An ``HTTPException`` is thrown when the file is not submitted.
+You can skip this check by making the controller argument nullable.
+
+.. code-block:: php-attributes
+
+    #[MapUploadedFile]
+    ?UploadedFile $document
+
+.. code-block:: php-attributes
+
+    #[MapUploadedFile]
+    UploadedFile|null $document
+
+``UploadedFile`` collections must be mapped to array or variadic arguments.
+The bound ``Constraints`` will be applied to each file in the collection.
+If a constraint violation is detected to one of them an ``HTTPException`` is thrown.
+
+.. code-block:: php-attributes
+
+    #[MapUploadedFile(new Assert\File(mimeTypes: ['application/pdf']))]
+    array $documents
+
+.. code-block:: php-attributes
+
+    #[MapUploadedFile(new Assert\File(mimeTypes: ['application/pdf']))]
+    UploadedFile ...$documents
+
+Handling custom names.
+
+.. code-block:: php-attributes
+
+    #[MapUploadedFile(name: 'something-else')]
+    UploadedFile $document
+
+Changing the ``HTTP Status`` thrown when constraint violations are detected.
+
+.. code-block:: php-attributes
+
+    #[MapUploadedFile(
+        constraints: new Assert\File(maxSize: '2M'),
+        validationFailedStatusCode: Response::HTTP_REQUEST_ENTITY_TOO_LARGE
+    )]
+    UploadedFile $document
+
+.. versionadded:: 7.1
+
+    The ``#[MapUploadedFile]`` attribute was introduced in Symfony 7.1.
+
 Managing the Session
 --------------------
 
diff --git a/reference/attributes.rst b/reference/attributes.rst
index a1e8532c347..4428dc4c587 100644
--- a/reference/attributes.rst
+++ b/reference/attributes.rst
@@ -64,6 +64,7 @@ HttpKernel
 * :ref:`MapQueryParameter <controller_map-request>`
 * :ref:`MapQueryString <controller_map-request>`
 * :ref:`MapRequestPayload <controller_map-request>`
+* :ref:`MapUploadedFile <controller_map-uploaded-file>`
 * :ref:`ValueResolver <managing-value-resolvers>`
 * :ref:`WithHttpStatus <framework_exceptions>`
 * :ref:`WithLogLevel <framework_exceptions>`

From 044be1e65529b555f35688fc84998e3dd18b374b Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 26 Apr 2024 16:11:47 +0200
Subject: [PATCH 240/747] Tweaks

---
 security/access_token.rst | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/security/access_token.rst b/security/access_token.rst
index 593c6404c7a..2aca75118a3 100644
--- a/security/access_token.rst
+++ b/security/access_token.rst
@@ -537,7 +537,7 @@ claims. To create your own user object from the claims, you must
 2) Configure the OidcTokenHandler
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The ``OidcTokenHandler`` requires the package ``web-token/jwt-library``.
+The ``OidcTokenHandler`` requires the ``web-token/jwt-library`` package.
 If you haven't installed it yet, run this command:
 
 .. code-block:: terminal
@@ -619,6 +619,11 @@ it and retrieve the user info from it:
             ;
         };
 
+.. versionadded:: 7.1
+
+    The support of multiple algorithms to sign the JWS was introduced in Symfony 7.1.
+    In previous versions, only the ``ES256`` algorithm was supported.
+
 Following the `OpenID Connect Specification`_, the ``sub`` claim is used by
 default as user identifier. To use another claim, specify it on the
 configuration:

From 9fafa5fa863bed33d56113f904f6dca279e06f4c Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Mon, 29 Apr 2024 12:19:06 +0200
Subject: [PATCH 241/747] Use PHP 8.2 for build

---
 .github/workflows/ci.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 778d3fd5a2b..09158fd099a 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -26,7 +26,7 @@ jobs:
             -   name: "Set-up PHP"
                 uses: shivammathur/setup-php@v2
                 with:
-                    php-version: 8.1
+                    php-version: 8.2
                     coverage: none
                     tools: "composer:v2"
 

From 11cd34d903362e897626a0d80110dd50da3ba7d4 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Mon, 29 Apr 2024 12:21:09 +0200
Subject: [PATCH 242/747] -

---
 bundles/configuration.rst | 4 ----
 bundles/extension.rst     | 4 ----
 2 files changed, 8 deletions(-)

diff --git a/bundles/configuration.rst b/bundles/configuration.rst
index 48b91c1713a..882e828aeb6 100644
--- a/bundles/configuration.rst
+++ b/bundles/configuration.rst
@@ -61,10 +61,6 @@ There are two different ways of creating friendly configuration for a bundle:
 Using the AbstractBundle Class
 ------------------------------
 
-.. versionadded:: 6.1
-
-    The ``AbstractBundle`` class was introduced in Symfony 6.1.
-
 In bundles extending the :class:`Symfony\\Component\\HttpKernel\\Bundle\\AbstractBundle`
 class, you can add all the logic related to processing the configuration in that class::
 
diff --git a/bundles/extension.rst b/bundles/extension.rst
index d2e3cd05b9d..e1e2dba3e6b 100644
--- a/bundles/extension.rst
+++ b/bundles/extension.rst
@@ -20,10 +20,6 @@ There are two different ways of doing it:
 Loading Services Directly in your Bundle Class
 ----------------------------------------------
 
-.. versionadded:: 6.1
-
-    The ``AbstractBundle`` class was introduced in Symfony 6.1.
-
 In bundles extending the :class:`Symfony\\Component\\HttpKernel\\Bundle\\AbstractBundle`
 class, you can define the :method:`Symfony\\Component\\HttpKernel\\Bundle\\AbstractBundle::loadExtension`
 method to load service definitions from configuration files::

From d7b56cd00b50d69db80c294e0ec8a6b0c87268f3 Mon Sep 17 00:00:00 2001
From: Damien Fernandes <damien.fernandes24@gmail.com>
Date: Mon, 29 Apr 2024 13:03:46 +0200
Subject: [PATCH 243/747] [Scheduler] Fix code sample

---
 scheduler.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scheduler.rst b/scheduler.rst
index 6a50a8e34ae..dd723c326c3 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -901,7 +901,7 @@ same task more than once::
                 ->with(
                     // ...
                 )
-                ->lock($this->lockFactory->createLock('my-lock')
+                ->lock($this->lockFactory->createLock('my-lock'));
         }
     }
 

From a209c5709324cea384f54097333c289d77153571 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Thu, 2 May 2024 08:50:08 +0200
Subject: [PATCH 244/747] rename the model_type option to input

---
 reference/forms/types/money.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/reference/forms/types/money.rst b/reference/forms/types/money.rst
index 8e2130a5909..5793097fe2f 100644
--- a/reference/forms/types/money.rst
+++ b/reference/forms/types/money.rst
@@ -76,8 +76,8 @@ If set to ``true``, the HTML input will be rendered as a native HTML5
 
     As HTML5 number format is normalized, it is incompatible with ``grouping`` option.
 
-model_type
-~~~~~~~~~~
+input
+~~~~~
 
 **type**: ``string`` **default**: ``float``
 
@@ -87,7 +87,7 @@ values stored in cents as integers) set this option to ``integer``.
 
 .. versionadded:: 7.1
 
-    The ``model_type`` option was introduced in Symfony 7.1.
+    The ``input`` option was introduced in Symfony 7.1.
 
 scale
 ~~~~~

From 90c5f4f9fabfa2fdca9a79e6c79fa70983e3922f Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Thu, 2 May 2024 11:43:31 +0200
Subject: [PATCH 245/747] deprecate the base_template_class option

---
 reference/configuration/twig.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst
index 1b9c1ef3bd9..596d70d8a2b 100644
--- a/reference/configuration/twig.rst
+++ b/reference/configuration/twig.rst
@@ -62,6 +62,10 @@ base_template_class
 
 **type**: ``string`` **default**: ``Twig\Template``
 
+.. deprecated:: 7.1
+
+    The ``base_template_class`` option is deprecated since Symfony 7.1.
+
 Twig templates are compiled into PHP classes before using them to render
 contents. This option defines the base class from which all the template classes
 extend. Using a custom base template is discouraged because it will make your

From dabb2d9f6976a2e475279d6caf24a3330649fc8e Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 7 May 2024 11:15:03 +0200
Subject: [PATCH 246/747] [Validator] Misc tweaks in MacAddress and Charset
 constraints

---
 reference/constraints/Charset.rst    |  4 ++--
 reference/constraints/MacAddress.rst | 14 +++++++-------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/reference/constraints/Charset.rst b/reference/constraints/Charset.rst
index 4f1a260356f..084f24cdf76 100644
--- a/reference/constraints/Charset.rst
+++ b/reference/constraints/Charset.rst
@@ -88,8 +88,8 @@ Options
 
 An encoding or a set of encodings to check against. If you pass an array of
 encodings, the validator will check if the value is encoded in *any* of the
-encodings. This option accepts any value that can be passed to
-:phpfunction:`mb_detect_encoding`.
+encodings. This option accepts any value that can be passed to the
+:phpfunction:`mb_detect_encoding` PHP function.
 
 .. include:: /reference/constraints/_groups-option.rst.inc
 
diff --git a/reference/constraints/MacAddress.rst b/reference/constraints/MacAddress.rst
index 2958af49874..59adffe7c11 100644
--- a/reference/constraints/MacAddress.rst
+++ b/reference/constraints/MacAddress.rst
@@ -19,18 +19,18 @@ Basic Usage
 -----------
 
 To use the MacAddress validator, apply it to a property on an object that
-will contain a host name.
+can contain a MAC address:
 
 .. configuration-block::
 
     .. code-block:: php-attributes
 
-        // src/Entity/Author.php
+        // src/Entity/Device.php
         namespace App\Entity;
 
         use Symfony\Component\Validator\Constraints as Assert;
 
-        class Author
+        class Device
         {
             #[Assert\MacAddress]
             protected string $mac;
@@ -39,7 +39,7 @@ will contain a host name.
     .. code-block:: yaml
 
         # config/validator/validation.yaml
-        App\Entity\Author:
+        App\Entity\Device:
             properties:
                 mac:
                     - MacAddress: ~
@@ -52,7 +52,7 @@ will contain a host name.
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
 
-            <class name="App\Entity\Author">
+            <class name="App\Entity\Device">
                 <property name="max">
                     <constraint name="MacAddress"/>
                 </property>
@@ -61,13 +61,13 @@ will contain a host name.
 
     .. code-block:: php
 
-        // src/Entity/Author.php
+        // src/Entity/Device.php
         namespace App\Entity;
 
         use Symfony\Component\Validator\Constraints as Assert;
         use Symfony\Component\Validator\Mapping\ClassMetadata;
 
-        class Author
+        class Device
         {
             // ...
 

From 979891b65830f123e846534119aab8e559b48d74 Mon Sep 17 00:00:00 2001
From: rahul <rcsofttech85@gmail.com>
Date: Tue, 7 May 2024 14:46:30 +0530
Subject: [PATCH 247/747] Removed unnecessary Request parameter

---
 security/csrf.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/security/csrf.rst b/security/csrf.rst
index 76aaf9ea4bf..a758c856f16 100644
--- a/security/csrf.rst
+++ b/security/csrf.rst
@@ -176,7 +176,7 @@ attribute on the controller action::
     // ...
 
     #[IsCsrfTokenValid('delete-item', tokenKey: 'token')]
-    public function delete(Request $request): Response
+    public function delete(): Response
     {
         // ... do something, like deleting an object
     }

From 846cbae795919e74ec57ee9d1010cb3ff16d4041 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 8 May 2024 12:52:24 +0200
Subject: [PATCH 248/747] Tweaks and rewords

---
 controller.rst | 83 +++++++++++++++++++++++++++-----------------------
 1 file changed, 45 insertions(+), 38 deletions(-)

diff --git a/controller.rst b/controller.rst
index ee6c2ecd194..cec5ce4b904 100644
--- a/controller.rst
+++ b/controller.rst
@@ -589,84 +589,91 @@ using the ``type`` option of the attribute::
 
 .. _controller_map-uploaded-file:
 
-Mapping Uploaded File
-~~~~~~~~~~~~~~~~~~~~~
+Mapping Uploaded Files
+~~~~~~~~~~~~~~~~~~~~~~
 
-You can map ``UploadedFile``s to the controller arguments and optionally bind ``Constraints`` to them.
-The argument resolver fetches the ``UploadedFile`` based on the argument name.
-
-::
+Symfony provides an attribute called ``#[MapUploadedFile]`` to map one or more
+``UploadedFile`` objects to controller arguments::
 
     namespace App\Controller;
 
+    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
     use Symfony\Component\HttpFoundation\File\UploadedFile;
     use Symfony\Component\HttpFoundation\Response;
     use Symfony\Component\HttpKernel\Attribute\MapUploadedFile;
     use Symfony\Component\Routing\Attribute\Route;
-    use Symfony\Component\Validator\Constraints as Assert;
 
-    #[Route('/user/picture', methods: ['PUT'])]
-    class ChangeUserPictureController
+    class UserController extends AbstractController
     {
-        public function _invoke(
-            #[MapUploadedFile([
-                new Assert\File(mimeTypes: ['image/png', 'image/jpeg']),
-                new Assert\Image(maxWidth: 3840, maxHeight: 2160)
-            ])]
-            UploadedFile $picture
+        #[Route('/user/picture', methods: ['PUT'])]
+        public function changePicture(
+            #[MapUploadedFile] UploadedFile $picture,
         ): Response {
             // ...
         }
     }
 
-.. tip::
-
-    The bound ``Constraints`` are performed before injecting the ``UploadedFile`` into the controller argument.
-    When a constraint violation is detected an ``HTTPException`` is thrown and the controller's
-    action is not executed.
-
-Mapping ``UploadedFile``s with no custom settings.
+In this example, the associated :doc:`argument resolver <controller/value_resolver>`
+fetches the ``UploadedFile`` based on the argument name (``$picture``). If no file
+is submitted, an ``HttpException`` is thrown. You can change this by making the
+controller argument nullable:
 
 .. code-block:: php-attributes
 
     #[MapUploadedFile]
-    UploadedFile $document
+    ?UploadedFile $document
 
-An ``HTTPException`` is thrown when the file is not submitted.
-You can skip this check by making the controller argument nullable.
+The ``#[MapUploadedFile]`` attribute also allows to pass a list of constraints
+to apply to the uploaded file::
 
-.. code-block:: php-attributes
+    namespace App\Controller;
 
-    #[MapUploadedFile]
-    ?UploadedFile $document
+    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+    use Symfony\Component\HttpFoundation\File\UploadedFile;
+    use Symfony\Component\HttpFoundation\Response;
+    use Symfony\Component\HttpKernel\Attribute\MapUploadedFile;
+    use Symfony\Component\Routing\Attribute\Route;
+    use Symfony\Component\Validator\Constraints as Assert;
 
-.. code-block:: php-attributes
+    class UserController extends AbstractController
+    {
+        #[Route('/user/picture', methods: ['PUT'])]
+        public function changePicture(
+            #[MapUploadedFile([
+                new Assert\File(mimeTypes: ['image/png', 'image/jpeg']),
+                new Assert\Image(maxWidth: 3840, maxHeight: 2160),
+            ])]
+            UploadedFile $picture,
+        ): Response {
+            // ...
+        }
+    }
 
-    #[MapUploadedFile]
-    UploadedFile|null $document
+The validation constraints are checked before injecting the ``UploadedFile`` into
+the controller argument. If there's a constraint violation, an ``HttpException``
+is thrown and the controller's action is not executed.
 
-``UploadedFile`` collections must be mapped to array or variadic arguments.
-The bound ``Constraints`` will be applied to each file in the collection.
-If a constraint violation is detected to one of them an ``HTTPException`` is thrown.
+If you need to upload a collection of files, map them to an array or a variadic
+argument. The given constraint will be applied to all files and if any of them
+fails, an ``HttpException`` is thrown:
 
 .. code-block:: php-attributes
 
     #[MapUploadedFile(new Assert\File(mimeTypes: ['application/pdf']))]
     array $documents
 
-.. code-block:: php-attributes
-
     #[MapUploadedFile(new Assert\File(mimeTypes: ['application/pdf']))]
     UploadedFile ...$documents
 
-Handling custom names.
+Use the ``name`` option to rename the uploaded file to a custom value:
 
 .. code-block:: php-attributes
 
     #[MapUploadedFile(name: 'something-else')]
     UploadedFile $document
 
-Changing the ``HTTP Status`` thrown when constraint violations are detected.
+In addition, you can change the status code of the HTTP exception thrown when
+there are constraint violations:
 
 .. code-block:: php-attributes
 

From e0a49ba49a8c6b1ca770cc8cfc659975212f2b7f Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Tue, 7 May 2024 16:13:00 +0200
Subject: [PATCH 249/747] [Security] Add support for dynamic CSRF id with
 Expression in `#[IsCsrfTokenValid]`

---
 security/csrf.rst | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/security/csrf.rst b/security/csrf.rst
index 76aaf9ea4bf..715ed8a5283 100644
--- a/security/csrf.rst
+++ b/security/csrf.rst
@@ -181,6 +181,32 @@ attribute on the controller action::
         // ... do something, like deleting an object
     }
 
+Suppose you want a CSRF token per item, so in the template you have something like the following:
+
+.. code-block:: html+twig
+
+    <form action="{{ url('admin_post_delete', { id: post.id }) }}" method="post">
+        {# the argument of csrf_token() is a dynamic id string used to generate the token #}
+        <input type="hidden" name="token" value="{{ csrf_token('delete-item-' ~ post.id) }}">
+
+        <button type="submit">Delete item</button>
+    </form>
+
+The :class:`Symfony\\Component\\Security\\Http\\Attribute\\IsCsrfTokenValid`
+attribute also accepts an :class:`Symfony\\Component\\ExpressionLanguage\\Expression`
+object evaluated to the id::
+
+    use Symfony\Component\HttpFoundation\Request;
+    use Symfony\Component\HttpFoundation\Response;
+    use Symfony\Component\Security\Http\Attribute\IsCsrfTokenValid;
+    // ...
+
+    #[IsCsrfTokenValid(new Expression('"delete-item-" ~ args["post"].id'), tokenKey: 'token')]
+    public function delete(Post $post): Response
+    {
+        // ... do something, like deleting an object
+    }
+
 .. versionadded:: 7.1
 
     The :class:`Symfony\\Component\\Security\\Http\\Attribute\\IsCsrfTokenValid`

From a40bf7c2d12b049a1190e0727c1096b95fe2908a Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Thu, 16 May 2024 13:20:12 +0200
Subject: [PATCH 250/747] -

---
 components/serializer.rst | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/components/serializer.rst b/components/serializer.rst
index 03583918304..9fc4c8d5417 100644
--- a/components/serializer.rst
+++ b/components/serializer.rst
@@ -1166,10 +1166,6 @@ Option                          Description
                                 following: ``<![CDATA[...]]>``
 ==============================  =================================================  ==========================
 
-.. versionadded:: 6.4
-
-    The `cdata_wrapping` option was introduced in Symfony 6.4.
-
 Example with custom ``context``::
 
     use Symfony\Component\Serializer\Encoder\XmlEncoder;

From c6d35123b955de9a0a7080f4b78fee3ec7b32ef1 Mon Sep 17 00:00:00 2001
From: alexpozzi <alexpozzi@users.noreply.github.com>
Date: Mon, 13 May 2024 17:49:41 +0200
Subject: [PATCH 251/747] Add missing XML serializer's CDATA options

---
 components/serializer.rst | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/components/serializer.rst b/components/serializer.rst
index 2d1ea2c7637..1c86a111084 100644
--- a/components/serializer.rst
+++ b/components/serializer.rst
@@ -1200,11 +1200,17 @@ Option                          Description
 ``remove_empty_tags``           If set to true, removes all empty tags in the      ``false``
                                 generated XML
 ``cdata_wrapping``              If set to false, will not wrap any value           ``true``
-                                containing one of the following characters (
-                                ``<``, ``>``, ``&``) in `a CDATA section`_ like
-                                following: ``<![CDATA[...]]>``
+                                matching the ``cdata_wrapping_pattern`` regex in
+                                `a CDATA section`_ like following:
+                                ``<![CDATA[...]]>``
+``cdata_wrapping_pattern``      A regular expression pattern to determine if a     ``/[<>&]/``
+                                value should be wrapped in a CDATA section
 ==============================  =================================================  ==========================
 
+.. versionadded:: 7.1
+
+    The `cdata_wrapping_pattern` option was introduced in Symfony 7.1.
+
 Example with custom ``context``::
 
     use Symfony\Component\Serializer\Encoder\XmlEncoder;

From 18f36ef332bae77634877b1bea756ae3230d82b6 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 22 May 2024 15:46:43 +0200
Subject: [PATCH 252/747] Fix some merging issues

---
 notifier.rst | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/notifier.rst b/notifier.rst
index 3e2c3eca6d9..b34757f22bf 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -165,6 +165,9 @@ Service
 `Smsapi`_           **Install**: ``composer require symfony/smsapi-notifier`` \
                     **DSN**: ``smsapi://TOKEN@default?from=FROM`` \
                     **Webhook support**: No
+`Smsbox`_           **Install**: ``composer require symfony/smsbox-notifier`` \
+                    **DSN**: ``smsbox://APIKEY@default?mode=MODE&strategy=STRATEGY&sender=SENDER`` \
+                    **Webhook support**: No
 `SmsBiuras`_        **Install**: ``composer require symfony/sms-biuras-notifier`` \
                     **DSN**: ``smsbiuras://UID:API_KEY@default?from=FROM&test_mode=0`` \
                     **Webhook support**: No
@@ -189,6 +192,9 @@ Service
 `Twilio`_           **Install**: ``composer require symfony/twilio-notifier`` \
                     **DSN**: ``twilio://SID:TOKEN@default?from=FROM`` \
                     **Webhook support**: Yes
+`Unifonic`_         **Install**: ``composer require symfony/unifonic-notifier`` \
+                    **DSN**: ``unifonic://APP_SID@default?from=FROM`` \
+                    **Webhook support**: No
 `Vonage`_           **Install**: ``composer require symfony/vonage-notifier`` \
                     **DSN**: ``vonage://KEY:SECRET@default?from=FROM`` \
                     **Webhook support**: Yes
@@ -205,7 +211,8 @@ Service
 
 .. versionadded:: 7.1
 
-    The `SmsSluzba`_, `SMSense`_  and `LOX24`_ integrations were introduced in Symfony 7.1.
+    The ``Smsbox``, ``SmsSluzba``, ``SMSense``, ``LOX24`` and ``Unifonic``
+    integrations were introduced in Symfony 7.1.
 
 .. deprecated:: 7.1
 
@@ -348,8 +355,7 @@ Service                                  Package                               D
 
 .. versionadded:: 7.1
 
-    The ``Bluesky``, ``Unifonic`` and ``Smsbox`` integrations
-    were introduced in Symfony 7.1.
+    The ``Bluesky`` integration was introduced in Symfony 7.1.
 
 .. caution::
 

From 01ca38dac8964f2e06eb18428854e9f3561a5a17 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Wed, 22 May 2024 21:44:11 +0200
Subject: [PATCH 253/747] [Stopwatch] Add ROOT constant to make it easier to
 reference

---
 performance.rst | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/performance.rst b/performance.rst
index ca34e95ee37..ffeff6608c1 100644
--- a/performance.rst
+++ b/performance.rst
@@ -382,10 +382,16 @@ All events that don't belong to any named section are added to the special secti
 called ``__root__``. This way you can get all stopwatch events, even if you don't
 know their names, as follows::
 
-    foreach($this->stopwatch->getSectionEvents('__root__') as $event) {
+    use Symfony\Component\Stopwatch\Stopwatch;
+
+    foreach($this->stopwatch->getSectionEvents(Stopwatch::ROOT) as $event) {
         echo (string) $event;
     }
 
+.. versionadded:: 7.2
+
+    The ``Stopwatch::ROOT`` constant as a shortcut for ``__root__`` was introduced in Symfony 7.2.
+
 Learn more
 ----------
 

From 6331dc5d6b6b52425220e5dec44f75be657ea2d7 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Wed, 22 May 2024 21:49:28 +0200
Subject: [PATCH 254/747] [Stopwatch] Add getLastPeriod method to
 StopwatchEvent

---
 performance.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/performance.rst b/performance.rst
index ca34e95ee37..634ad8572ea 100644
--- a/performance.rst
+++ b/performance.rst
@@ -362,6 +362,13 @@ method does, which stops an event and then restarts it immediately::
     // Lap information is stored as "periods" within the event:
     // $event->getPeriods();
 
+    // Gets the last event period:
+    // $event->getLastPeriod();
+
+.. versionadded:: 7.2
+
+    The ``getLastPeriod`` method was introduced in Symfony 7.2.
+
 Profiling Sections
 ..................
 

From 5bcaf58a7608ad467dffc3be35721d9e3286b4c1 Mon Sep 17 00:00:00 2001
From: Tim <5579551+Timherlaud@users.noreply.github.com>
Date: Wed, 22 May 2024 16:31:48 +0200
Subject: [PATCH 255/747] 19909 [FrameworkBundle] Add support for setting
 headers

---
 templates.rst | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/templates.rst b/templates.rst
index b6ae333cee1..d1c714d4225 100644
--- a/templates.rst
+++ b/templates.rst
@@ -705,6 +705,11 @@ provided by Symfony:
                     site_name: 'ACME'
                     theme: 'dark'
 
+                # optionally you can define HTTP headers to add to the response
+                headers:
+                    Content-Type: 'text/html'
+                    foo: 'bar'
+
     .. code-block:: xml
 
         <!-- config/routes.xml -->
@@ -734,6 +739,11 @@ provided by Symfony:
                     <default key="site_name">ACME</default>
                     <default key="theme">dark</default>
                 </default>
+
+                <!-- optionally you can define HTTP headers to add to the response -->
+                <default key="headers">
+                    <default key="Content-Type">text/html</default>
+                </default>
             </route>
         </routes>
 
@@ -764,11 +774,20 @@ provided by Symfony:
                     'context' => [
                         'site_name' => 'ACME',
                         'theme' => 'dark',
+                        ],
+
+                    // optionally you can define HTTP headers to add to the response
+                    'headers' => [
+                        'Content-Type' => 'text/html',
                     ]
                 ])
             ;
         };
 
+.. versionadded:: 7.2
+
+    The ``headers`` option was introduced in Symfony 7.2.
+
 Checking if a Template Exists
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From a9a6f77c095d34d3bb2c6b7e65fd26fb7f2e371d Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Fri, 24 May 2024 15:50:07 +0200
Subject: [PATCH 256/747] Update examples to symfony 7.2

---
 contributing/code/pull_requests.rst | 2 +-
 contributing/code/tests.rst         | 2 +-
 setup.rst                           | 8 ++++----
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/contributing/code/pull_requests.rst b/contributing/code/pull_requests.rst
index 7c9ab2579a5..28a6dbc8169 100644
--- a/contributing/code/pull_requests.rst
+++ b/contributing/code/pull_requests.rst
@@ -132,7 +132,7 @@ work:
   branch (you can find them on the `Symfony releases page`_). E.g. if you
   found a bug introduced in ``v5.1.10``, you need to work on ``5.4``.
 
-* ``7.1``, if you are adding a new feature.
+* ``7.2``, if you are adding a new feature.
 
   The only exception is when a new :doc:`major Symfony version </contributing/community/releases>`
   (5.0, 6.0, etc.) comes out every two years. Because of the
diff --git a/contributing/code/tests.rst b/contributing/code/tests.rst
index 08f6bc5df12..060e3eda02b 100644
--- a/contributing/code/tests.rst
+++ b/contributing/code/tests.rst
@@ -32,7 +32,7 @@ tests, such as Doctrine, Twig and Monolog. To do so,
 
     .. code-block:: terminal
 
-        $ COMPOSER_ROOT_VERSION=7.1.x-dev composer update
+        $ COMPOSER_ROOT_VERSION=7.2.x-dev composer update
 
 .. _running:
 
diff --git a/setup.rst b/setup.rst
index 90a89e78e8a..5cf3d2f90ab 100644
--- a/setup.rst
+++ b/setup.rst
@@ -48,10 +48,10 @@ application:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ symfony new my_project_directory --version="7.1.*" --webapp
+    $ symfony new my_project_directory --version="7.2.*" --webapp
 
     # run this if you are building a microservice, console application or API
-    $ symfony new my_project_directory --version="7.1.*"
+    $ symfony new my_project_directory --version="7.2.*"
 
 The only difference between these two commands is the number of packages
 installed by default. The ``--webapp`` option installs extra packages to give
@@ -63,12 +63,12 @@ Symfony application using Composer:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ composer create-project symfony/skeleton:"7.1.*" my_project_directory
+    $ composer create-project symfony/skeleton:"7.2.*" my_project_directory
     $ cd my_project_directory
     $ composer require webapp
 
     # run this if you are building a microservice, console application or API
-    $ composer create-project symfony/skeleton:"7.1.*" my_project_directory
+    $ composer create-project symfony/skeleton:"7.2.*" my_project_directory
 
 No matter which command you run to create the Symfony application. All of them
 will create a new ``my_project_directory/`` directory, download some dependencies

From 92d1b5a8728b7c83930e497a7c86e1f0b6abcb1f Mon Sep 17 00:00:00 2001
From: Yannick <tech@yalit.be>
Date: Tue, 21 May 2024 23:52:53 +0200
Subject: [PATCH 257/747] [Validator] feat : add password strength estimator
 related documentation

---
 reference/constraints/PasswordStrength.rst    |  9 ++++
 .../get_or_override_estimate_strength.rst     | 48 +++++++++++++++++++
 2 files changed, 57 insertions(+)
 create mode 100644 validation/passwordStrength/get_or_override_estimate_strength.rst

diff --git a/reference/constraints/PasswordStrength.rst b/reference/constraints/PasswordStrength.rst
index 989ffddd100..a44fd70fd4e 100644
--- a/reference/constraints/PasswordStrength.rst
+++ b/reference/constraints/PasswordStrength.rst
@@ -128,3 +128,12 @@ The default message supplied when the password does not reach the minimum requir
         ])]
         protected $rawPassword;
     }
+
+Learn more
+----------
+
+.. toctree::
+    :maxdepth: 1
+    :glob:
+
+    /validation/passwordStrength/*
diff --git a/validation/passwordStrength/get_or_override_estimate_strength.rst b/validation/passwordStrength/get_or_override_estimate_strength.rst
new file mode 100644
index 00000000000..9cd24c1b818
--- /dev/null
+++ b/validation/passwordStrength/get_or_override_estimate_strength.rst
@@ -0,0 +1,48 @@
+How to Get or Override the Default Password Strength Estimation Algorithm
+=========================================================================
+
+Within the :class:`Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator` a `dedicated function`_ is used to estimate the strength of the given password. This function can be retrieved directly from the :class:`Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator` class and can also be overridden.
+
+Get the default Password strength
+---------------------------------
+
+In case of need to retrieve the actual strength of a password (e.g. compute the score and display it when the user has defined a password), the ``estimateStrength`` `dedicated function`_ of the :class:`Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator` is a public static function, therefore this function can be retrieved directly from the `PasswordStrengthValidator` class.::
+
+        use Symfony\Component\Validator\Constraints\PasswordStrengthValidator;
+
+        $passwordEstimatedStrength = PasswordStrengthValidator::estimateStrength($password);
+
+
+Override the default Password strength estimation algorithm
+-----------------------------------------------------------
+
+If you need to override the default password strength estimation algorithm, you can pass a ``Closure`` to the :class:`Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator` constructor. This can be done using the :doc:`/service_container/service_closures`.
+
+First, create a custom password strength estimation algorithm within a dedicated callable class.::
+
+        namespace App\Validator;
+
+        class CustomPasswordStrengthEstimator
+        {
+            /**
+             * @param string $password
+             *
+             * @return PasswordStrength::STRENGTH_*
+             */
+            public function __invoke(string $password): int
+            {
+                // Your custom password strength estimation algorithm
+            }
+        }
+
+Then, configure the :class:`Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator` service to use the custom password strength estimation algorithm.::
+
+        # config/services.yaml
+        services:
+            custom_password_strength_estimator:
+                class: App\Validator\CustomPasswordStrengthEstimator
+
+            Symfony\Component\Validator\Constraints\PasswordStrengthValidator:
+                arguments: [!service_closure '@custom_password_strength_estimator']
+
+.. _`dedicated function`: https://github.com/symfony/symfony/blob/85db734e06e8cb32365810958326d48084bf48ba/src/Symfony/Component/Validator/Constraints/PasswordStrengthValidator.php#L53-L90

From f6b69918adf973068635a9f39e1e4be5c1f4dc40 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 28 May 2024 10:43:26 +0200
Subject: [PATCH 258/747] Move the docs to the constraint doc

---
 reference/constraints/PasswordStrength.rst    | 87 +++++++++++++++++--
 .../get_or_override_estimate_strength.rst     | 48 ----------
 2 files changed, 81 insertions(+), 54 deletions(-)
 delete mode 100644 validation/passwordStrength/get_or_override_estimate_strength.rst

diff --git a/reference/constraints/PasswordStrength.rst b/reference/constraints/PasswordStrength.rst
index a44fd70fd4e..671b5f495ef 100644
--- a/reference/constraints/PasswordStrength.rst
+++ b/reference/constraints/PasswordStrength.rst
@@ -129,11 +129,86 @@ The default message supplied when the password does not reach the minimum requir
         protected $rawPassword;
     }
 
-Learn more
-----------
+Customizing the Password Strength Estimation
+--------------------------------------------
 
-.. toctree::
-    :maxdepth: 1
-    :glob:
+.. versionadded:: 7.2
 
-    /validation/passwordStrength/*
+    The feature to customize the password strength estimation was introduced in Symfony 7.2.
+
+By default, this constraint calculates the strength of a password based on its
+length and the number of unique characters used. You can get the calculated
+password strength (e.g. to display it in the user interface) using the following
+static function::
+
+    use Symfony\Component\Validator\Constraints\PasswordStrengthValidator;
+
+    $passwordEstimatedStrength = PasswordStrengthValidator::estimateStrength($password);
+
+If you need to override the default password strength estimation algorithm, you
+can pass a ``Closure`` to the :class:`Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator`
+constructor (e.g. using the :doc:`service closures </service_container/service_closures>`).
+
+First, create a custom password strength estimation algorithm within a dedicated
+callable class::
+
+    namespace App\Validator;
+
+    class CustomPasswordStrengthEstimator
+    {
+        /**
+         * @return PasswordStrength::STRENGTH_*
+         */
+        public function __invoke(string $password): int
+        {
+            // Your custom password strength estimation algorithm
+        }
+    }
+
+Then, configure the :class:`Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator`
+service to use your own estimator:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/services.yaml
+        services:
+            custom_password_strength_estimator:
+                class: App\Validator\CustomPasswordStrengthEstimator
+
+            Symfony\Component\Validator\Constraints\PasswordStrengthValidator:
+                arguments: [!service_closure '@custom_password_strength_estimator']
+
+    .. code-block:: xml
+
+        <!-- config/services.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
+
+            <services>
+                <service id="custom_password_strength_estimator" class="App\Validator\CustomPasswordStrengthEstimator"/>
+
+                <service id="Symfony\Component\Validator\Constraints\PasswordStrengthValidator">
+                    <argument type="service_closure" id="custom_password_strength_estimator"/>
+                </service>
+            </services>
+        </container>
+
+    .. code-block:: php
+
+        // config/services.php
+        namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+        use Symfony\Component\Validator\Constraints\PasswordStrengthValidator;
+
+        return function (ContainerConfigurator $container): void {
+            $services = $container->services();
+
+            $services->set('custom_password_strength_estimator', CustomPasswordStrengthEstimator::class);
+
+            $services->set(PasswordStrengthValidator::class)
+                ->args([service_closure('custom_password_strength_estimator')]);
+        };
diff --git a/validation/passwordStrength/get_or_override_estimate_strength.rst b/validation/passwordStrength/get_or_override_estimate_strength.rst
deleted file mode 100644
index 9cd24c1b818..00000000000
--- a/validation/passwordStrength/get_or_override_estimate_strength.rst
+++ /dev/null
@@ -1,48 +0,0 @@
-How to Get or Override the Default Password Strength Estimation Algorithm
-=========================================================================
-
-Within the :class:`Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator` a `dedicated function`_ is used to estimate the strength of the given password. This function can be retrieved directly from the :class:`Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator` class and can also be overridden.
-
-Get the default Password strength
----------------------------------
-
-In case of need to retrieve the actual strength of a password (e.g. compute the score and display it when the user has defined a password), the ``estimateStrength`` `dedicated function`_ of the :class:`Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator` is a public static function, therefore this function can be retrieved directly from the `PasswordStrengthValidator` class.::
-
-        use Symfony\Component\Validator\Constraints\PasswordStrengthValidator;
-
-        $passwordEstimatedStrength = PasswordStrengthValidator::estimateStrength($password);
-
-
-Override the default Password strength estimation algorithm
------------------------------------------------------------
-
-If you need to override the default password strength estimation algorithm, you can pass a ``Closure`` to the :class:`Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator` constructor. This can be done using the :doc:`/service_container/service_closures`.
-
-First, create a custom password strength estimation algorithm within a dedicated callable class.::
-
-        namespace App\Validator;
-
-        class CustomPasswordStrengthEstimator
-        {
-            /**
-             * @param string $password
-             *
-             * @return PasswordStrength::STRENGTH_*
-             */
-            public function __invoke(string $password): int
-            {
-                // Your custom password strength estimation algorithm
-            }
-        }
-
-Then, configure the :class:`Symfony\\Component\\Validator\\Constraints\\PasswordStrengthValidator` service to use the custom password strength estimation algorithm.::
-
-        # config/services.yaml
-        services:
-            custom_password_strength_estimator:
-                class: App\Validator\CustomPasswordStrengthEstimator
-
-            Symfony\Component\Validator\Constraints\PasswordStrengthValidator:
-                arguments: [!service_closure '@custom_password_strength_estimator']
-
-.. _`dedicated function`: https://github.com/symfony/symfony/blob/85db734e06e8cb32365810958326d48084bf48ba/src/Symfony/Component/Validator/Constraints/PasswordStrengthValidator.php#L53-L90

From 710d306fba10953ab91b9b1994295564b8afebb2 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 29 May 2024 12:16:03 +0200
Subject: [PATCH 259/747] [Notifier] Add a missing reference link

---
 notifier.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/notifier.rst b/notifier.rst
index 202689005a3..5346fbf7719 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -1089,6 +1089,7 @@ is dispatched. Listeners receive a
 .. _`RocketChat`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/RocketChat/README.md
 .. _`SMSFactor`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SmsFactor/README.md
 .. _`Sendberry`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sendberry/README.md
+.. _`Sendinblue`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sendinblue/README.md
 .. _`SimpleTextin`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SimpleTextin/README.md
 .. _`Sinch`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sinch/README.md
 .. _`Slack`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Slack/README.md

From f6a398b498d77c19627f93c3328a75017b78d16c Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 29 May 2024 12:04:38 +0200
Subject: [PATCH 260/747] Move some docs from the Choice constraint to the
 ChoiceType

---
 reference/constraints/Choice.rst | 26 --------------------------
 reference/forms/types/choice.rst | 26 ++++++++++++++++++++++++++
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/reference/constraints/Choice.rst b/reference/constraints/Choice.rst
index 8bafaaede7b..5a9c365be37 100644
--- a/reference/constraints/Choice.rst
+++ b/reference/constraints/Choice.rst
@@ -389,29 +389,3 @@ Parameter        Description
 ===============  ==============================================================
 
 .. include:: /reference/constraints/_payload-option.rst.inc
-
-``separator``
-~~~~~~~~~~~~~
-
-**type**: ``string`` **default**: ``-------------------``
-
-This option allows you to customize the visual separator shown after the preferred
-choices. You can use HTML elements like ``<hr>`` to display a more modern separator,
-but you'll also need to set the `separator_html`_ option to ``true``.
-
-.. versionadded:: 7.1
-
-    The ``separator`` option was introduced in Symfony 7.1.
-
-``separator_html``
-~~~~~~~~~~~~~~~~~~
-
-**type**: ``boolean`` **default**: ``false``
-
-If this option is true, the `separator`_ option will be displayed as HTML instead
-of text. This is useful when using HTML elements (e.g. ``<hr>``) as a more modern
-visual separator.
-
-.. versionadded:: 7.1
-
-    The ``separator_html`` option was introduced in Symfony 7.1.
diff --git a/reference/forms/types/choice.rst b/reference/forms/types/choice.rst
index 3637da8bdca..0b250b799da 100644
--- a/reference/forms/types/choice.rst
+++ b/reference/forms/types/choice.rst
@@ -202,6 +202,32 @@ correct types will be assigned to the model.
 
 .. include:: /reference/forms/types/options/preferred_choices.rst.inc
 
+``separator``
+~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``-------------------``
+
+This option allows you to customize the visual separator shown after the preferred
+choices. You can use HTML elements like ``<hr>`` to display a more modern separator,
+but you'll also need to set the `separator_html`_ option to ``true``.
+
+.. versionadded:: 7.1
+
+    The ``separator`` option was introduced in Symfony 7.1.
+
+``separator_html``
+~~~~~~~~~~~~~~~~~~
+
+**type**: ``boolean`` **default**: ``false``
+
+If this option is true, the `separator`_ option will be displayed as HTML instead
+of text. This is useful when using HTML elements (e.g. ``<hr>``) as a more modern
+visual separator.
+
+.. versionadded:: 7.1
+
+    The ``separator_html`` option was introduced in Symfony 7.1.
+
 Overridden Options
 ------------------
 

From 41c4ce5f15986ad8dfb95d3267f875cff63e9377 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Thu, 30 May 2024 11:41:26 +0200
Subject: [PATCH 261/747] [Dotenv] Fix `SYMFONY_DOTENV_PATH` purpose

---
 configuration.rst | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/configuration.rst b/configuration.rst
index 728f0e4e8b5..36dceae1b71 100644
--- a/configuration.rst
+++ b/configuration.rst
@@ -954,15 +954,7 @@ path is part of the options you can set in your ``composer.json`` file:
           }
       }
 
-You can also set the ``SYMFONY_DOTENV_PATH`` environment variable at system
-level (e.g. in your web server configuration or in your Dockerfile):
-
-.. code-block:: bash
-
-    # .env (or .env.local)
-    SYMFONY_DOTENV_PATH=my/custom/path/to/.env
-
-Finally, you can directly invoke the ``Dotenv`` class in your
+As an alternate option, you can directly invoke the ``Dotenv`` class in your
 ``bootstrap.php`` file or any other file of your application::
 
     use Symfony\Component\Dotenv\Dotenv;
@@ -975,9 +967,13 @@ the local and environment-specific files (e.g. ``.*.local`` and
 :ref:`how to override environment variables <configuration-multiple-env-files>`
 to learn more about this.
 
+If you need to know the path to the ``.env`` file that Symfony is using, you can
+read the ``SYMFONY_DOTENV_PATH`` environment variable in your application.
+
 .. versionadded:: 7.1
 
-    The ``SYMFONY_DOTENV_PATH`` environment variable was introduced in Symfony 7.1.
+    The ``SYMFONY_DOTENV_PATH`` environment variable was introduced in Symfony
+    7.1.
 
 .. _configuration-secrets:
 

From 0074962a87b9598d337469566266f9d78a8f742a Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Mon, 27 May 2024 16:19:49 +0200
Subject: [PATCH 262/747] [Emoji] Add the text locale

---
 string.rst | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/string.rst b/string.rst
index c58a736da89..9253b89478e 100644
--- a/string.rst
+++ b/string.rst
@@ -561,6 +561,7 @@ textual representation in all languages based on the `Unicode CLDR dataset`_::
 
 The ``EmojiTransliterator`` also provides special locales that convert emojis to
 short codes and vice versa in specific platforms, such as GitHub, Gitlab and Slack.
+All theses platform are also combined in special locale ``text``.
 
 GitHub Emoji Transliteration
 ............................
@@ -607,6 +608,27 @@ Convert Slack short codes to emojis with the ``slack-emoji`` locale::
     $transliterator->transliterate('Menus with :green_salad: or :falafel:');
     // => 'Menus with 🥗 or 🧆'
 
+Text Emoji Transliteration
+..........................
+
+If you don't know where short codes come from, you can use the ``text-emoji`` locale.
+This locale will convert Github, Gitlab and Slack short codes to emojis::
+
+    $transliterator = EmojiTransliterator::create('text-emoji');
+    // Github short codes
+    $transliterator->transliterate('Breakfast with :kiwi-fruit: or :milk-glass:');
+    // Gitlab short codes
+    $transliterator->transliterate('Breakfast with :kiwi: or :milk:');
+    // Slack short codes
+    $transliterator->transliterate('Breakfast with :kiwifruit: or :glass-of-milk:');
+    // => 'Breakfast with 🥝 or 🥛'
+
+You can convert emojis to short codes with the ``emoji-text`` locale::
+
+    $transliterator = EmojiTransliterator::create('emoji-text');
+    $transliterator->transliterate('Breakfast with 🥝 or 🥛');
+    // => 'Breakfast with :kiwifruit: or :milk-glass:
+
 Removing Emojis
 ~~~~~~~~~~~~~~~
 

From cd3690d3738ff210cd2144f97186c2acce20e38f Mon Sep 17 00:00:00 2001
From: A goazil <samael.tomas@gmail.com>
Date: Tue, 30 Apr 2024 09:52:48 +0200
Subject: [PATCH 263/747] [Notifier] add Primotexto bridge

chore: add versionadded directive
---
 notifier.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/notifier.rst b/notifier.rst
index 04ca5a2d4a4..01dfaf17cc6 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -138,6 +138,9 @@ Service
 `Plivo`_            **Install**: ``composer require symfony/plivo-notifier`` \
                     **DSN**: ``plivo://AUTH_ID:AUTH_TOKEN@default?from=FROM`` \
                     **Webhook support**: No
+`Primotexto`_       **Install**: ``composer require symfony/primotexto-notifier`` \
+                    **DSN**: ``primotexto://API_KEY@default?from=FROM`` \
+                    **Webhook support**: No
 `Redlink`_          **Install**: ``composer require symfony/redlink-notifier`` \
                     **DSN**: ``redlink://API_KEY:APP_KEY@default?from=SENDER_NAME&version=API_VERSION`` \
                     **Webhook support**: No
@@ -203,6 +206,10 @@ Service
                     **Webhook support**: No
 ==================  ====================================================================================================================================
 
+.. versionadded:: 7.2
+
+    The ``Primotexto`` integration was introduced in Symfony 7.2.
+
 .. tip::
 
     Some third party transports, when using the API, support status callbacks
@@ -1119,6 +1126,7 @@ is dispatched. Listeners receive a
 .. _`OvhCloud`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/OvhCloud/README.md
 .. _`PagerDuty`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/PagerDuty/README.md
 .. _`Plivo`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Plivo/README.md
+.. _`Primotexto`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Primotexto/README.md
 .. _`Pushover`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Pushover/README.md
 .. _`Pushy`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Pushy/README.md
 .. _`Redlink`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Redlink/README.md

From 69c39f5f7e54a7ba2b9d7b449ef4269baed4b761 Mon Sep 17 00:00:00 2001
From: Jean-David Daviet <jeandaviddaviet@gmail.com>
Date: Fri, 31 May 2024 15:00:17 +0200
Subject: [PATCH 264/747] Fix broken link for UriSigner::sign method

---
 routing.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/routing.rst b/routing.rst
index 790ae314516..153c3690824 100644
--- a/routing.rst
+++ b/routing.rst
@@ -2697,7 +2697,7 @@ service, which you can inject in your services or controllers::
 For security reasons, it's common to make signed URIs expire after some time
 (e.g. when using them to reset user credentials). By default, signed URIs don't
 expire, but you can define an expiration date/time using the ``$expiration``
-argument of :phpmethod:`Symfony\\Component\\HttpFoundation\\UriSigner::sign`::
+argument of :method:`Symfony\\Component\\HttpFoundation\\UriSigner::sign`::
 
     // src/Service/SomeService.php
     namespace App\Service;

From dc23e2e0399768c26c495ed8e2cf481843801d57 Mon Sep 17 00:00:00 2001
From: Maximilian Beckers <beckers.maximilian@gmail.com>
Date: Tue, 4 Jun 2024 12:01:10 +0200
Subject: [PATCH 265/747] [Validator] BicValidator add strict mode to validate
 bics in strict mode

---
 reference/constraints/Bic.rst | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/reference/constraints/Bic.rst b/reference/constraints/Bic.rst
index 69ce35248f3..a6a745e3a76 100644
--- a/reference/constraints/Bic.rst
+++ b/reference/constraints/Bic.rst
@@ -121,4 +121,24 @@ Parameter        Description
 
 .. include:: /reference/constraints/_payload-option.rst.inc
 
+``mode``
+~~~~~~~~
+
+**type**: ``string`` **default**: ``strict``
+
+The mode in which the BIC is validated can be defined with this option. Valid values are:
+
+* ``strict`` uses the input BIC and validates it without modification.
+* ``case-insensitive`` converts the input value to uppercase before validating the BIC.
+
+.. tip::
+
+    The possible values of this option are also defined as PHP constants of
+    :class:`Symfony\\Component\\Validator\\Constraints\\BIC`
+    (e.g. ``BIC::VALIDATION_MODE_CASE_INSENSITIVE``).
+
+.. versionadded:: 7.2
+
+    The ``mode`` option was introduced in Symfony 7.2.
+
 .. _`Business Identifier Code (BIC)`: https://en.wikipedia.org/wiki/Business_Identifier_Code

From 8be7bb3f34064492907af7d1de2eb5b3f27d75de Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 30 May 2024 15:29:28 +0200
Subject: [PATCH 266/747] [String] Update the emoji transliteration docs

---
 string.rst | 40 ++++++++++++++++++++++++----------------
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/string.rst b/string.rst
index 9253b89478e..01752fff9c9 100644
--- a/string.rst
+++ b/string.rst
@@ -558,15 +558,20 @@ textual representation in all languages based on the `Unicode CLDR dataset`_::
     $transliterator->transliterate('Menus with 🍕 or 🍝');
     // => 'Menus with піца or спагеті'
 
+Transliterating Emoji Text Short Codes
+......................................
 
-The ``EmojiTransliterator`` also provides special locales that convert emojis to
-short codes and vice versa in specific platforms, such as GitHub, Gitlab and Slack.
-All theses platform are also combined in special locale ``text``.
+Services like GitHub and Slack allows to include emojis in your messages using
+text short codes (e.g. you can add the ``:+1:`` code to render the 👍 emoji).
 
-GitHub Emoji Transliteration
-............................
+Symfony also provides a feature to transliterate emojis into short codes and vice
+versa. The short codes are slightly different on each service, so you must pass
+the name of the service as an argument when creating the transliterator:
 
-Convert GitHub emojis to short codes with the ``emoji-github`` locale::
+GitHub Emoji Short Codes Transliteration
+########################################
+
+Convert emojis to GitHub short codes with the ``emoji-github`` locale::
 
     $transliterator = EmojiTransliterator::create('emoji-github');
     $transliterator->transliterate('Teenage 🐢 really love 🍕');
@@ -578,10 +583,10 @@ Convert GitHub short codes to emojis with the ``github-emoji`` locale::
     $transliterator->transliterate('Teenage :turtle: really love :pizza:');
     // => 'Teenage 🐢 really love 🍕'
 
-Gitlab Emoji Transliteration
-............................
+Gitlab Emoji Short Codes Transliteration
+########################################
 
-Convert Gitlab emojis to short codes with the ``emoji-gitlab`` locale::
+Convert emojis to Gitlab short codes with the ``emoji-gitlab`` locale::
 
     $transliterator = EmojiTransliterator::create('emoji-gitlab');
     $transliterator->transliterate('Breakfast with 🥝 or 🥛');
@@ -593,10 +598,10 @@ Convert Gitlab short codes to emojis with the ``gitlab-emoji`` locale::
     $transliterator->transliterate('Breakfast with :kiwi: or :milk:');
     // => 'Breakfast with 🥝 or 🥛'
 
-Slack Emoji Transliteration
-...........................
+Slack Emoji Short Codes Transliteration
+#######################################
 
-Convert Slack emojis to short codes with the ``emoji-slack`` locale::
+Convert emojis to Slack short codes with the ``emoji-slack`` locale::
 
     $transliterator = EmojiTransliterator::create('emoji-slack');
     $transliterator->transliterate('Menus with 🥗 or 🧆');
@@ -608,19 +613,22 @@ Convert Slack short codes to emojis with the ``slack-emoji`` locale::
     $transliterator->transliterate('Menus with :green_salad: or :falafel:');
     // => 'Menus with 🥗 or 🧆'
 
-Text Emoji Transliteration
-..........................
+Universal Emoji Short Codes Transliteration
+###########################################
 
-If you don't know where short codes come from, you can use the ``text-emoji`` locale.
-This locale will convert Github, Gitlab and Slack short codes to emojis::
+If you don't know which service was used to generate the short codes, you can use
+the ``text-emoji`` locale, which combines all codes from all services::
 
     $transliterator = EmojiTransliterator::create('text-emoji');
+
     // Github short codes
     $transliterator->transliterate('Breakfast with :kiwi-fruit: or :milk-glass:');
     // Gitlab short codes
     $transliterator->transliterate('Breakfast with :kiwi: or :milk:');
     // Slack short codes
     $transliterator->transliterate('Breakfast with :kiwifruit: or :glass-of-milk:');
+
+    // all the above examples produce the same result:
     // => 'Breakfast with 🥝 or 🥛'
 
 You can convert emojis to short codes with the ``emoji-text`` locale::

From 1484f9dc53b784ac79b1b5cb3f7fd000f07ac92c Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 5 Jun 2024 11:40:33 +0200
Subject: [PATCH 267/747] Minor tweaks

---
 reference/constraints/Bic.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/reference/constraints/Bic.rst b/reference/constraints/Bic.rst
index a6a745e3a76..3f05e5eac25 100644
--- a/reference/constraints/Bic.rst
+++ b/reference/constraints/Bic.rst
@@ -126,10 +126,10 @@ Parameter        Description
 
 **type**: ``string`` **default**: ``strict``
 
-The mode in which the BIC is validated can be defined with this option. Valid values are:
+This option defines how the BIC is validated:
 
-* ``strict`` uses the input BIC and validates it without modification.
-* ``case-insensitive`` converts the input value to uppercase before validating the BIC.
+* ``strict`` validates the given value without any modification;
+* ``case-insensitive`` converts the given value to uppercase before validating it.
 
 .. tip::
 

From fd6262225b0e14b3b35690e24b94f14f56a47e83 Mon Sep 17 00:00:00 2001
From: seb-jean <sebastien.jean76@gmail.com>
Date: Thu, 6 Jun 2024 16:36:12 +0200
Subject: [PATCH 268/747] Update csrf.rst

---
 security/csrf.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/security/csrf.rst b/security/csrf.rst
index 77aad6bf090..11c7b2fc267 100644
--- a/security/csrf.rst
+++ b/security/csrf.rst
@@ -233,7 +233,7 @@ object evaluated to the id::
     use Symfony\Component\Security\Http\Attribute\IsCsrfTokenValid;
     // ...
 
-    #[IsCsrfTokenValid(new Expression('"delete-item-" ~ args["post"].id'), tokenKey: 'token')]
+    #[IsCsrfTokenValid(new Expression('"delete-item-" ~ args["post"].getId()'), tokenKey: 'token')]
     public function delete(Post $post): Response
     {
         // ... do something, like deleting an object

From 1f4115ea993cf1e31f11dc96de64b0ec3da85c47 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Fri, 7 Jun 2024 08:53:11 +0200
Subject: [PATCH 269/747] fix markup

---
 components/serializer.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/serializer.rst b/components/serializer.rst
index 1c86a111084..6a5790fd48f 100644
--- a/components/serializer.rst
+++ b/components/serializer.rst
@@ -1209,7 +1209,7 @@ Option                          Description
 
 .. versionadded:: 7.1
 
-    The `cdata_wrapping_pattern` option was introduced in Symfony 7.1.
+    The ``cdata_wrapping_pattern`` option was introduced in Symfony 7.1.
 
 Example with custom ``context``::
 

From 0624d24867ba378c160c0c56fa3127490ca2b065 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 13 Jun 2024 16:48:16 +0200
Subject: [PATCH 270/747] [ExpressionLanguage] Document the null-coalesce
 operator changes

---
 reference/formats/expression_language.rst | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/reference/formats/expression_language.rst b/reference/formats/expression_language.rst
index c7ce82fb751..818870452a5 100644
--- a/reference/formats/expression_language.rst
+++ b/reference/formats/expression_language.rst
@@ -124,11 +124,10 @@ returns the right-hand side. Expressions can chain multiple coalescing operators
 * ``foo[3] ?? 'no'``
 * ``foo.baz ?? foo['baz'] ?? 'no'``
 
-.. note::
+.. versionadded:: 7.2
 
-    The main difference with the `null-coalescing operator in PHP`_ is that
-    ExpressionLanguage will throw an exception when trying to access a
-    non-existent variable.
+    Starting from Symfony 7.2, no exception is thrown when trying to access a
+    non-existent variable. This is the same behavior as the `null-coalescing operator in PHP`_.
 
 .. _component-expression-functions:
 

From 00854911226a5f2ec7299e0e0345fcaacba110ac Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 13 Jun 2024 17:34:08 +0200
Subject: [PATCH 271/747] [Translation] Document `lint:translations` command

---
 translation.rst | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/translation.rst b/translation.rst
index 891f00845cb..0fbd155cfd7 100644
--- a/translation.rst
+++ b/translation.rst
@@ -1343,7 +1343,7 @@ Symfony processes all the application translation files as part of the process
 that compiles the application code before executing it. If there's an error in
 any translation file, you'll see an error message explaining the problem.
 
-If you prefer, you can also validate the contents of any YAML and XLIFF
+If you prefer, you can also validate the syntax of any YAML and XLIFF
 translation file using the ``lint:yaml`` and ``lint:xliff`` commands:
 
 .. code-block:: terminal
@@ -1384,6 +1384,22 @@ adapted to the format required by GitHub, but you can force that format too:
 
         $ php vendor/bin/yaml-lint translations/
 
+The ``lint:yaml`` and ``lint:xliff`` commands validate the YAML and XML syntax
+of the translation files, but not their contents. Use the following command
+to check that the translation contents are also correct:
+
+    .. code-block:: terminal
+
+        # checks the contents of all the translation catalogues in all locales
+        $ php bin/console lint:translations
+
+        # checks the contents of the translation catalogues for Italian (it) and Japanese (ja) locales
+        $ php bin/console lint:translations --locales=it --locales=ja
+
+.. versionadded:: 7.2
+
+    The ``lint:translations`` command was introduced in Symfony 7.2.
+
 Pseudo-localization translator
 ------------------------------
 

From 29bdb1612d2a3d7387cad50228cbe226623ea4ec Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 17 Jun 2024 10:36:30 +0200
Subject: [PATCH 272/747] Update the version constraints

---
 setup.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/setup.rst b/setup.rst
index 5cf3d2f90ab..d8196e71b7b 100644
--- a/setup.rst
+++ b/setup.rst
@@ -48,10 +48,10 @@ application:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ symfony new my_project_directory --version="7.2.*" --webapp
+    $ symfony new my_project_directory --version="7.2.x-dev" --webapp
 
     # run this if you are building a microservice, console application or API
-    $ symfony new my_project_directory --version="7.2.*"
+    $ symfony new my_project_directory --version="7.2.x-dev"
 
 The only difference between these two commands is the number of packages
 installed by default. The ``--webapp`` option installs extra packages to give
@@ -63,12 +63,12 @@ Symfony application using Composer:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ composer create-project symfony/skeleton:"7.2.*" my_project_directory
+    $ composer create-project symfony/skeleton:"7.2.x-dev" my_project_directory
     $ cd my_project_directory
     $ composer require webapp
 
     # run this if you are building a microservice, console application or API
-    $ composer create-project symfony/skeleton:"7.2.*" my_project_directory
+    $ composer create-project symfony/skeleton:"7.2.x-dev" my_project_directory
 
 No matter which command you run to create the Symfony application. All of them
 will create a new ``my_project_directory/`` directory, download some dependencies

From fd7b8eac82104bb10eb8ecc8791d3d7dd75a2b34 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 17 Jun 2024 13:26:52 +0200
Subject: [PATCH 273/747] Add the versionadded directive

---
 security/access_token.rst | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/security/access_token.rst b/security/access_token.rst
index d0ed785ad31..8661a226a73 100644
--- a/security/access_token.rst
+++ b/security/access_token.rst
@@ -709,6 +709,10 @@ create your own User from the claims, you must
 Using CAS 2.0
 -------------
 
+.. versionadded:: 7.1
+
+    The support for CAS token handlers was introduced in Symfony 7.1.
+
 `Central Authentication Service (CAS)`_ is an enterprise multilingual single
 sign-on solution and identity provider for the web and attempts to be a
 comprehensive platform for your authentication and authorization needs.
@@ -724,7 +728,7 @@ haven't installed it yet, run this command:
 
     $ composer require symfony/http-client
 
-You can configure a ``cas`` ``token_handler``:
+You can configure a ``cas`` token handler as follows:
 
 .. configuration-block::
 

From 0050ebae4c477b9f1aa30e2c86526e6827820efe Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 18 Jun 2024 16:03:27 +0200
Subject: [PATCH 274/747] [FrameworkBundle] Remove some unneeded versionadded
 directives

---
 configuration/micro_kernel_trait.rst  | 4 ----
 reference/configuration/framework.rst | 4 ----
 2 files changed, 8 deletions(-)

diff --git a/configuration/micro_kernel_trait.rst b/configuration/micro_kernel_trait.rst
index 6b90a3d7ddb..b67335514a1 100644
--- a/configuration/micro_kernel_trait.rst
+++ b/configuration/micro_kernel_trait.rst
@@ -120,10 +120,6 @@ Next, create an ``index.php`` file that defines the kernel class and runs it:
         $response->send();
         $kernel->terminate($request, $response);
 
-.. versionadded:: 6.1
-
-    The PHP attributes notation has been introduced in Symfony 6.1.
-
 .. note::
 
     In addition to the ``index.php`` file, you'll need to create a directory called
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 6e93c4568b9..fec52229973 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -972,10 +972,6 @@ crypto_method
 The minimum version of TLS to accept. The value must be one of the
 ``STREAM_CRYPTO_METHOD_TLSv*_CLIENT`` constants defined by PHP.
 
-.. versionadded:: 6.3
-
-    The ``crypto_method`` option was introduced in Symfony 6.3.
-
 .. _reference-http-client-retry-delay:
 
 delay

From d25c009b180ca57b0449fad9c285ceae780110e7 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 11 Apr 2024 11:53:36 +0200
Subject: [PATCH 275/747] [Emoji][Twig] Add `emojify` filter

---
 reference/twig_reference.rst | 31 +++++++++++++++++++++++++++++++
 string.rst                   | 29 +++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/reference/twig_reference.rst b/reference/twig_reference.rst
index fcd95ce9b6e..812b56f8637 100644
--- a/reference/twig_reference.rst
+++ b/reference/twig_reference.rst
@@ -645,6 +645,37 @@ serialize
 Accepts any data that can be serialized by the :doc:`Serializer component </serializer>`
 and returns a serialized string in the specified ``format``.
 
+.. _reference-twig-filter-emojify:
+
+emojify
+~~~~~~~
+
+.. versionadded:: 7.1
+
+    The ``emojify`` filter was introduced in Symfony 7.1.
+
+.. code-block:: twig
+
+    {{ text|emojify(catalog = null) }}
+
+``text``
+    **type**: ``string``
+
+``catalog`` *(optional)*
+    **type**: ``string`` | ``null``
+
+    The emoji set used to generate the textual representation (``slack``,
+    ``github``, ``gitlab``, etc.)
+
+It transforms the textual representation of an emoji (e.g. ``:wave:``) into the
+actual emoji (👋):
+
+.. code-block:: twig
+
+    {{ ':+1:'|emojify }}                 {# renders: 👍 #}
+    {{ ':+1:'|emojify('github') }}       {# renders: 👍 #}
+    {{ ':thumbsup:'|emojify('gitlab') }} {# renders: 👍 #}
+
 .. _reference-twig-tags:
 
 Tags
diff --git a/string.rst b/string.rst
index 01752fff9c9..5e18cfcaea3 100644
--- a/string.rst
+++ b/string.rst
@@ -613,6 +613,8 @@ Convert Slack short codes to emojis with the ``slack-emoji`` locale::
     $transliterator->transliterate('Menus with :green_salad: or :falafel:');
     // => 'Menus with 🥗 or 🧆'
 
+.. _string-text-emoji:
+
 Universal Emoji Short Codes Transliteration
 ###########################################
 
@@ -637,6 +639,33 @@ You can convert emojis to short codes with the ``emoji-text`` locale::
     $transliterator->transliterate('Breakfast with 🥝 or 🥛');
     // => 'Breakfast with :kiwifruit: or :milk-glass:
 
+Inverse Emoji Transliteration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 7.1
+
+    The inverse emoji transliteration was introduced in Symfony 7.1.
+
+Given the textual representation of an emoji, you can reverse it back to get the
+actual emoji thanks to the :ref:`emojify filter <reference-twig-filter-emojify>`:
+
+.. code-block:: twig
+
+    {{ 'I like :kiwi-fruit:'|emojify }} {# renders: I like 🥝 #}
+    {{ 'I like :kiwi:'|emojify }}       {# renders: I like 🥝 #}
+    {{ 'I like :kiwifruit:'|emojify }}  {# renders: I like 🥝 #}
+
+By default, ``emojify`` uses the :ref:`text catalog <string-text-emoji>`, which
+merges the emoji text codes of all services. If you prefer, you can select a
+specific catalog to use:
+
+.. code-block:: twig
+
+    {{ 'I :green-heart: this'|emojify }}                  {# renders: I 💚 this #}
+    {{ ':green_salad: is nice'|emojify('slack') }}        {# renders: 🥗 is nice #}
+    {{ 'My :turtle: has no name yet'|emojify('github') }} {# renders: My 🐢 has no name yet #}
+    {{ ':kiwi: is a great fruit'|emojify('gitlab') }}     {# renders: 🥝 is a great fruit #}
+
 Removing Emojis
 ~~~~~~~~~~~~~~~
 

From 15dcd7e221ae7caca0cec61f56b2adab1cdd9b55 Mon Sep 17 00:00:00 2001
From: Patrick Landolt <patrick.landolt@artack.ch>
Date: Sun, 9 Jun 2024 18:19:11 +0200
Subject: [PATCH 276/747] [Mailer] Add mailomat mailer

---
 mailer.rst  | 10 ++++++++++
 webhook.rst |  5 +++++
 2 files changed, 15 insertions(+)

diff --git a/mailer.rst b/mailer.rst
index d7bccb11d86..502644a741a 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -106,6 +106,7 @@ Service               Install with                                    Webhook su
 `Infobip`_            ``composer require symfony/infobip-mailer``
 `Mailgun`_            ``composer require symfony/mailgun-mailer``     yes
 `Mailjet`_            ``composer require symfony/mailjet-mailer``     yes
+`Mailomat`_           ``composer require symfony/mailomat-mailer``    yes
 `MailPace`_           ``composer require symfony/mail-pace-mailer``
 `MailerSend`_         ``composer require symfony/mailer-send-mailer``
 `Mandrill`_           ``composer require symfony/mailchimp-mailer``
@@ -119,6 +120,10 @@ Service               Install with                                    Webhook su
 
     The Azure and Resend integrations were introduced in Symfony 7.1.
 
+.. versionadded:: 7.2
+
+    The Mailomat integration was introduced in Symfony 7.2.
+
 .. note::
 
     As a convenience, Symfony also provides support for Gmail (``composer
@@ -201,6 +206,10 @@ party provider:
 |                        | - HTTP n/a                                              |
 |                        | - API ``mailjet+api://ACCESS_KEY:SECRET_KEY@default``   |
 +------------------------+---------------------------------------------------------+
+| `Mailomat`_            | - SMTP ``mailomat+smtp://USERNAME:PASSWORD@default``    |
+|                        | - HTTP n/a                                              |
+|                        | - API ``mailomat+api://KEY@default``                    |
++------------------------+---------------------------------------------------------+
 | `MailPace`_            | - SMTP ``mailpace+api://API_TOKEN@default``             |
 |                        | - HTTP n/a                                              |
 |                        | - API ``mailpace+api://API_TOKEN@default``              |
@@ -1979,6 +1988,7 @@ the :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\MailerAssertionsTrait`::
 .. _`Mailgun`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Mailgun/README.md
 .. _`Mailjet`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Mailjet/README.md
 .. _`Markdown syntax`: https://commonmark.org/
+.. _`Mailomat`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Mailomat/README.md
 .. _`MailPace`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/MailPace/README.md
 .. _`OpenSSL PHP extension`: https://www.php.net/manual/en/book.openssl.php
 .. _`PEM encoded`: https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail
diff --git a/webhook.rst b/webhook.rst
index 38f3a4b1004..52633ae83e5 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -27,6 +27,7 @@ Brevo          ``mailer.webhook.request_parser.brevo``
 MailerSend     ``mailer.webhook.request_parser.mailersend``
 Mailgun        ``mailer.webhook.request_parser.mailgun``
 Mailjet        ``mailer.webhook.request_parser.mailjet``
+Mailomat       ``mailer.webhook.request_parser.mailomat``
 Postmark       ``mailer.webhook.request_parser.postmark``
 Resend         ``mailer.webhook.request_parser.resend``
 Sendgrid       ``mailer.webhook.request_parser.sendgrid``
@@ -36,6 +37,10 @@ Sendgrid       ``mailer.webhook.request_parser.sendgrid``
 
     The support for ``Resend`` and ``MailerSend`` were introduced in Symfony 7.1.
 
+.. versionadded:: 7.2
+
+    The ``Mailomat`` integration was introduced in Symfony 7.2.
+
 .. note::
 
     Install the third-party mailer provider you want to use as described in the

From 7cdfb52930f9097fef14ed56a3c8d6624461cb52 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 19 Jun 2024 09:20:04 +0200
Subject: [PATCH 277/747] [FrameworkBundle] Simplified the MicroKernelTrait
 setup

---
 configuration/micro_kernel_trait.rst | 107 +++++++++++++++------------
 1 file changed, 60 insertions(+), 47 deletions(-)

diff --git a/configuration/micro_kernel_trait.rst b/configuration/micro_kernel_trait.rst
index b67335514a1..23aa677cf20 100644
--- a/configuration/micro_kernel_trait.rst
+++ b/configuration/micro_kernel_trait.rst
@@ -16,9 +16,7 @@ via Composer:
 
 .. code-block:: terminal
 
-    $ composer require symfony/config symfony/http-kernel \
-      symfony/http-foundation symfony/routing \
-      symfony/dependency-injection symfony/framework-bundle
+    $ composer symfony/framework-bundle symfony/runtime
 
 Next, create an ``index.php`` file that defines the kernel class and runs it:
 
@@ -34,19 +32,12 @@ Next, create an ``index.php`` file that defines the kernel class and runs it:
         use Symfony\Component\HttpKernel\Kernel as BaseKernel;
         use Symfony\Component\Routing\Attribute\Route;
 
-        require __DIR__.'/vendor/autoload.php';
+        require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
 
         class Kernel extends BaseKernel
         {
             use MicroKernelTrait;
 
-            public function registerBundles(): array
-            {
-                return [
-                    new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
-                ];
-            }
-
             protected function configureContainer(ContainerConfigurator $container): void
             {
                 // PHP equivalent of config/packages/framework.yaml
@@ -64,11 +55,9 @@ Next, create an ``index.php`` file that defines the kernel class and runs it:
             }
         }
 
-        $kernel = new Kernel('dev', true);
-        $request = Request::createFromGlobals();
-        $response = $kernel->handle($request);
-        $response->send();
-        $kernel->terminate($request, $response);
+        return static function (array $context) {
+            return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
+        }
 
     .. code-block:: php
 
@@ -80,19 +69,12 @@ Next, create an ``index.php`` file that defines the kernel class and runs it:
         use Symfony\Component\HttpKernel\Kernel as BaseKernel;
         use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
 
-        require __DIR__.'/vendor/autoload.php';
+        require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
 
         class Kernel extends BaseKernel
         {
             use MicroKernelTrait;
 
-            public function registerBundles(): array
-            {
-                return [
-                    new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
-                ];
-            }
-
             protected function configureContainer(ContainerConfigurator $container): void
             {
                 // PHP equivalent of config/packages/framework.yaml
@@ -114,17 +96,9 @@ Next, create an ``index.php`` file that defines the kernel class and runs it:
             }
         }
 
-        $kernel = new Kernel('dev', true);
-        $request = Request::createFromGlobals();
-        $response = $kernel->handle($request);
-        $response->send();
-        $kernel->terminate($request, $response);
-
-.. note::
-
-    In addition to the ``index.php`` file, you'll need to create a directory called
-    ``config/`` in your project (even if it's empty because you define the configuration
-    options inside the ``configureContainer()`` method).
+        return static function (array $context) {
+            return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
+        }
 
 That's it! To test it, start the :doc:`Symfony Local Web Server
 </setup/symfony_server>`:
@@ -135,6 +109,23 @@ That's it! To test it, start the :doc:`Symfony Local Web Server
 
 Then see the JSON response in your browser: http://localhost:8000/random/10
 
+.. tip::
+
+    If your kernel only defines a single controller, you can use an invokable method::
+
+        class Kernel extends BaseKernel
+        {
+            use MicroKernelTrait;
+
+            // ...
+
+            #[Route('/random/{limit}', name: 'random_number')]
+            public function __invoke(int $limit): JsonResponse
+            {
+                // ...
+            }
+        }
+
 The Methods of a "Micro" Kernel
 -------------------------------
 
@@ -142,7 +133,26 @@ When you use the ``MicroKernelTrait``, your kernel needs to have exactly three m
 that define your bundles, your services and your routes:
 
 **registerBundles()**
-    This is the same ``registerBundles()`` that you see in a normal kernel.
+    This is the same ``registerBundles()`` that you see in a normal kernel. By
+    default, the micro kernel only registers the ``FrameworkBundle``. If you need
+    to register more bundles, override this method::
+
+        use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
+        use Symfony\Bundle\TwigBundle\TwigBundle;
+        // ...
+
+        class Kernel extends BaseKernel
+        {
+            use MicroKernelTrait;
+
+            // ...
+
+            public function registerBundles(): array
+            {
+                yield new FrameworkBundle();
+                yield new TwigBundle();
+            }
+        }
 
 **configureContainer(ContainerConfigurator $container)**
     This method builds and configures the container. In practice, you will use
@@ -151,9 +161,13 @@ that define your bundles, your services and your routes:
     services directly in PHP or load external configuration files (shown below).
 
 **configureRoutes(RoutingConfigurator $routes)**
-    Your job in this method is to add routes to the application. The
-    ``RoutingConfigurator`` has methods that make adding routes in PHP more
-    fun. You can also load external routing files (shown below).
+    In this method, you can use the ``RoutingConfigurator`` object to define routes
+    in your application and associate them to the controllers defined in this very
+    same file.
+
+    However, it's more convenient to define the controller routes using PHP attributes,
+    as shown above. That's why this method is commonly used only to load external
+    routing files (e.g. from bundles) as shown below.
 
 Adding Interfaces to "Micro" Kernel
 -----------------------------------
@@ -231,7 +245,10 @@ Now it looks like this::
     namespace App;
 
     use App\DependencyInjection\AppExtension;
+    use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
     use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
+    use Symfony\Bundle\TwigBundle\TwigBundle;
+    use Symfony\Bundle\WebProfilerBundle\WebProfilerBundle;
     use Symfony\Component\DependencyInjection\ContainerBuilder;
     use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
     use Symfony\Component\HttpKernel\Kernel as BaseKernel;
@@ -241,18 +258,14 @@ Now it looks like this::
     {
         use MicroKernelTrait;
 
-        public function registerBundles(): array
+        public function registerBundles(): iterable
         {
-            $bundles = [
-                new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
-                new \Symfony\Bundle\TwigBundle\TwigBundle(),
-            ];
+            yield FrameworkBundle();
+            yield TwigBundle();
 
             if ('dev' === $this->getEnvironment()) {
-                $bundles[] = new \Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
+                yield WebProfilerBundle();
             }
-
-            return $bundles;
         }
 
         protected function build(ContainerBuilder $containerBuilder): void

From d68d6abc1120c766b42498468a6667695ee16805 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 25 Jun 2024 09:43:08 +0200
Subject: [PATCH 278/747] [Validator] Add the format option to the Ulid
 constraint to allow accepting different ULID formats

---
 reference/constraints/Ulid.rst | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/reference/constraints/Ulid.rst b/reference/constraints/Ulid.rst
index ed7dfe7ed96..4ba5ec3a3f5 100644
--- a/reference/constraints/Ulid.rst
+++ b/reference/constraints/Ulid.rst
@@ -73,6 +73,20 @@ Basic Usage
 Options
 -------
 
+``format``
+~~~~~~~~~~
+
+**type**: ``string`` **default**: ``Ulid::FORMAT_BASE_32``
+
+The format of the ULID to validate. The following formats are available:
+
+* ``Ulid::FORMAT_BASE_32``: The ULID is encoded in base32 (default)
+* ``Ulid::FORMAT_BASE_58``: The ULID is encoded in base58
+
+.. versionadded:: 7.2
+
+    The ``format`` option was introduced in Symfony 7.2.
+
 .. include:: /reference/constraints/_groups-option.rst.inc
 
 ``message``

From ea63cd7d932c1b77ee589938dda2d3e03c0a9aca Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 25 Jun 2024 10:49:40 +0200
Subject: [PATCH 279/747] [Messenger] Document the --format option of
 messenger:stats command

---
 messenger.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index 3dab2caac52..785cc022136 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -688,6 +688,14 @@ of some or all transports:
     # shows stats only for some transports
     $ php bin/console messenger:stats my_transport_name other_transport_name
 
+    # you can also output the stats in JSON format
+    $ php bin/console messenger:stats --format=json
+    $ php bin/console messenger:stats my_transport_name other_transport_name --format=json
+
+.. versionadded:: 7.2
+
+    The ``format`` option was introduced in Symfony 7.2.
+
 .. note::
 
     In order for this command to work, the configured transport's receiver must implement

From 688db2816b0892982b0e2b2ab02fa9cf6a7f0573 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 14 Jun 2024 16:56:00 +0200
Subject: [PATCH 280/747] [Validator] Add the Yaml constraint

---
 components/yaml.rst            |   2 +
 reference/constraints/Yaml.rst | 152 +++++++++++++++++++++++++++++++++
 2 files changed, 154 insertions(+)
 create mode 100644 reference/constraints/Yaml.rst

diff --git a/components/yaml.rst b/components/yaml.rst
index 5f724e0572c..2698aae8233 100644
--- a/components/yaml.rst
+++ b/components/yaml.rst
@@ -214,6 +214,8 @@ During the parsing of the YAML contents, all the ``_`` characters are removed
 from the numeric literal contents, so there is not a limit in the number of
 underscores you can include or the way you group contents.
 
+.. _yaml-flags:
+
 Advanced Usage: Flags
 ---------------------
 
diff --git a/reference/constraints/Yaml.rst b/reference/constraints/Yaml.rst
new file mode 100644
index 00000000000..49b65f251e8
--- /dev/null
+++ b/reference/constraints/Yaml.rst
@@ -0,0 +1,152 @@
+Yaml
+====
+
+Validates that a value has valid `YAML`_ syntax.
+
+.. versionadded:: 7.2
+
+    The ``Yaml`` constraint was introduced in Symfony 7.2.
+
+==========  ===================================================================
+Applies to  :ref:`property or method <validation-property-target>`
+Class       :class:`Symfony\\Component\\Validator\\Constraints\\Yaml`
+Validator   :class:`Symfony\\Component\\Validator\\Constraints\\YamlValidator`
+==========  ===================================================================
+
+Basic Usage
+-----------
+
+The ``Yaml`` constraint can be applied to a property or a "getter" method:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Entity/Report.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+
+        class Report
+        {
+            #[Assert\Yaml(
+                message: "Your configuration doesn't have valid YAML syntax."
+            )]
+            private string $customConfiguration;
+        }
+
+    .. code-block:: yaml
+
+        # config/validator/validation.yaml
+        App\Entity\Report:
+            properties:
+                customConfiguration:
+                    - Yaml:
+                        message: Your configuration doesn't have valid YAML syntax.
+
+    .. code-block:: xml
+
+        <!-- config/validator/validation.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
+
+            <class name="App\Entity\Report">
+                <property name="customConfiguration">
+                    <constraint name="Yaml">
+                        <option name="message">Your configuration doesn't have valid YAML syntax.</option>
+                    </constraint>
+                </property>
+            </class>
+        </constraint-mapping>
+
+    .. code-block:: php
+
+        // src/Entity/Report.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+        use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+        class Report
+        {
+            public static function loadValidatorMetadata(ClassMetadata $metadata): void
+            {
+                $metadata->addPropertyConstraint('customConfiguration', new Assert\Yaml([
+                    'message' => 'Your configuration doesn\'t have valid YAML syntax.',
+                ]));
+            }
+        }
+
+Options
+-------
+
+``flags``
+~~~~~~~~~
+
+**type**: ``integer`` **default**: ``0``
+
+This option enables optional features of the YAML parser when validating contents.
+Its value is a combination of one or more of the :ref:`flags defined by the Yaml component <yaml-flags>`:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Entity/Report.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+        use Symfony\Component\Yaml\Yaml;
+
+        class Report
+        {
+            #[Assert\Yaml(
+                message: "Your configuration doesn't have valid YAML syntax.",
+                flags: Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS | Yaml::PARSE_DATETIME,
+            )]
+            private string $customConfiguration;
+        }
+
+    .. code-block:: php
+
+        // src/Entity/Report.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+        use Symfony\Component\Validator\Mapping\ClassMetadata;
+        use Symfony\Component\Yaml\Yaml;
+
+        class Report
+        {
+            public static function loadValidatorMetadata(ClassMetadata $metadata): void
+            {
+                $metadata->addPropertyConstraint('customConfiguration', new Assert\Yaml([
+                    'message' => 'Your configuration doesn\'t have valid YAML syntax.',
+                    'flags' => Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS | Yaml::PARSE_DATETIME,
+                ]));
+            }
+        }
+
+``message``
+~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``This value is not valid YAML.``
+
+This message shown if the underlying data is not a valid YAML value.
+
+You can use the following parameters in this message:
+
+===============  ==============================================================
+Parameter        Description
+===============  ==============================================================
+``{{ error }}``  The full error message from the YAML parser
+``{{ line }}``   The line where the YAML syntax error happened
+===============  ==============================================================
+
+.. include:: /reference/constraints/_groups-option.rst.inc
+
+.. include:: /reference/constraints/_payload-option.rst.inc
+
+.. _`YAML`: https://en.wikipedia.org/wiki/YAML

From feabd16bf91dbafe52d1379b2d61a45bcfffdba0 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 25 Jun 2024 17:26:55 +0200
Subject: [PATCH 281/747] [DoctrineBridge] Allow EntityValueResolver to return
 a list of entities

---
 doctrine.rst | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/doctrine.rst b/doctrine.rst
index 00418319105..770a7b32a0a 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -741,6 +741,20 @@ In the expression, the ``repository`` variable will be your entity's
 Repository class and any route wildcards - like ``{product_id}`` are
 available as variables.
 
+The repository method called in the expression can also return a list of entities.
+In that case, update the type of your controller argument::
+
+    #[Route('/posts_by/{author_id}')]
+    public function authorPosts(
+        #[MapEntity(class: Post::class, expr: 'repository.findBy({"author": author_id}, {}, 10)')]
+        iterable $posts
+    ): Response {
+    }
+
+.. versionadded:: 7.1
+
+    The mapping of the lists of entities was introduced in Symfony 7.1.
+
 This can also be used to help resolve multiple arguments::
 
     #[Route('/product/{id}/comments/{comment_id}')]

From c3fdc75c27551e2a09bb5298b1d47e7e759ac60c Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 26 Jun 2024 09:01:07 +0200
Subject: [PATCH 282/747] [ExpressionLanguage] Add support for comments

---
 reference/formats/expression_language.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/reference/formats/expression_language.rst b/reference/formats/expression_language.rst
index 818870452a5..e88ac7f6c24 100644
--- a/reference/formats/expression_language.rst
+++ b/reference/formats/expression_language.rst
@@ -20,6 +20,11 @@ The component supports:
 * **booleans** - ``true`` and ``false``
 * **null** - ``null``
 * **exponential** - also known as scientific (e.g. ``1.99E+3`` or ``1e-2``)
+* **comments** - using ``/*`` and ``*/`` (e.g. ``/* this is a comment */``)
+
+.. versionadded:: 7.2
+
+    The support for comments inside expressions was introduced in Symfony 7.2.
 
 .. caution::
 

From 39be3e699885a57f91a2b30a4f34855465f1ec03 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 26 Jun 2024 09:55:47 +0200
Subject: [PATCH 283/747] [DependencyInjection] Add `#[WhenNot]` attribute

---
 reference/attributes.rst |  1 +
 service_container.rst    | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/reference/attributes.rst b/reference/attributes.rst
index 4428dc4c587..d744cb9a9b4 100644
--- a/reference/attributes.rst
+++ b/reference/attributes.rst
@@ -43,6 +43,7 @@ Dependency Injection
 * :ref:`TaggedLocator <service-subscribers-locators_defining-service-locator>`
 * :ref:`Target <autowiring-multiple-implementations-same-type>`
 * :ref:`When <service-container_limiting-to-env>`
+* :ref:`WhenNot <service-container_limiting-to-env>`
 
 EventDispatcher
 ~~~~~~~~~~~~~~~
diff --git a/service_container.rst b/service_container.rst
index ebc01b1fc8a..bc8e5f123b1 100644
--- a/service_container.rst
+++ b/service_container.rst
@@ -260,6 +260,32 @@ as a service in some environments::
         // ...
     }
 
+If you want to exclude a service from being registered in a specific
+environment, you can use the ``#[WhenNot]`` attribute::
+
+    use Symfony\Component\DependencyInjection\Attribute\WhenNot;
+
+    // SomeClass is registered in all environments except "dev"
+
+    #[WhenNot(env: 'dev')]
+    class SomeClass
+    {
+        // ...
+    }
+
+    // you can apply more than one WhenNot attribute to the same class
+
+    #[WhenNot(env: 'dev')]
+    #[WhenNot(env: 'test')]
+    class AnotherClass
+    {
+        // ...
+    }
+
+.. versionadded:: 7.2
+
+    The ``#[WhenNot]`` attribute was introduced in Symfony 7.2.
+
 .. _services-constructor-injection:
 
 Injecting Services/Config into a Service

From 28070e85a3ea9ff4357150604d03c1582811b26c Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 28 Jun 2024 16:44:59 +0200
Subject: [PATCH 284/747] [Serializer] Remove any mention to annotations

---
 components/serializer.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/components/serializer.rst b/components/serializer.rst
index c23e6300a4d..40a114b543e 100644
--- a/components/serializer.rst
+++ b/components/serializer.rst
@@ -264,8 +264,8 @@ Assume you have the following plain-old-PHP object::
         }
     }
 
-The definition of serialization can be specified using annotations, attributes, XML
-or YAML. The :class:`Symfony\\Component\\Serializer\\Mapping\\Factory\\ClassMetadataFactory`
+The definition of serialization can be specified using attributes, XML or YAML.
+The :class:`Symfony\\Component\\Serializer\\Mapping\\Factory\\ClassMetadataFactory`
 that will be used by the normalizer must be aware of the format to use.
 
 The following code shows how to initialize the :class:`Symfony\\Component\\Serializer\\Mapping\\Factory\\ClassMetadataFactory`

From d669eb32e6af05f5f34ce3953abf385336eeaed3 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Sun, 30 Jun 2024 16:16:58 +0200
Subject: [PATCH 285/747] deprecate TaggedIterator and TaggedLocator attributes

---
 reference/attributes.rst                      |  8 +++++++
 .../service_subscribers_locators.rst          | 24 ++++++++++++++-----
 service_container/tags.rst                    | 24 +++++++++----------
 3 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/reference/attributes.rst b/reference/attributes.rst
index 4428dc4c587..ba34afd524d 100644
--- a/reference/attributes.rst
+++ b/reference/attributes.rst
@@ -44,6 +44,14 @@ Dependency Injection
 * :ref:`Target <autowiring-multiple-implementations-same-type>`
 * :ref:`When <service-container_limiting-to-env>`
 
+.. deprecated:: 7.1
+
+    The
+    :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator`
+    and
+    :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator`
+    were deprecated in Symfony 7.1.
+
 EventDispatcher
 ~~~~~~~~~~~~~~~
 
diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst
index 25ebe97e7e7..9c36f8c82cd 100644
--- a/service_container/service_subscribers_locators.rst
+++ b/service_container/service_subscribers_locators.rst
@@ -307,6 +307,18 @@ This is done by having ``getSubscribedServices()`` return an array of
         ];
     }
 
+.. deprecated:: 7.1
+
+    The
+    :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator`
+    and
+    :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator`
+    were deprecated in Symfony 7.1.
+    :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireIterator`
+    and
+    :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireLocator`
+    should be used instead.
+
 .. note::
 
     The above example requires using ``3.2`` version or newer of ``symfony/service-contracts``.
@@ -432,13 +444,13 @@ or directly via PHP attributes:
         namespace App;
 
         use Psr\Container\ContainerInterface;
-        use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
+        use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
 
         class CommandBus
         {
             public function __construct(
                 // creates a service locator with all the services tagged with 'app.handler'
-                #[TaggedLocator('app.handler')]
+                #[AutowireLocator('app.handler')]
                 private ContainerInterface $locator,
             ) {
             }
@@ -674,12 +686,12 @@ to index the services:
         namespace App;
 
         use Psr\Container\ContainerInterface;
-        use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
+        use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
 
         class CommandBus
         {
             public function __construct(
-                #[TaggedLocator('app.handler', indexAttribute: 'key')]
+                #[AutowireLocator('app.handler', indexAttribute: 'key')]
                 private ContainerInterface $locator,
             ) {
             }
@@ -789,12 +801,12 @@ get the value used to index the services:
         namespace App;
 
         use Psr\Container\ContainerInterface;
-        use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
+        use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
 
         class CommandBus
         {
             public function __construct(
-                #[TaggedLocator('app.handler', 'defaultIndexMethod: 'getLocatorKey')]
+                #[AutowireLocator('app.handler', 'defaultIndexMethod: 'getLocatorKey')]
                 private ContainerInterface $locator,
             ) {
             }
diff --git a/service_container/tags.rst b/service_container/tags.rst
index 1900ce28fb2..68509bc5620 100644
--- a/service_container/tags.rst
+++ b/service_container/tags.rst
@@ -674,13 +674,13 @@ directly via PHP attributes:
         // src/HandlerCollection.php
         namespace App;
 
-        use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
+        use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
 
         class HandlerCollection
         {
             public function __construct(
                 // the attribute must be applied directly to the argument to autowire
-                #[TaggedIterator('app.handler')]
+                #[AutowireIterator('app.handler')]
                 iterable $handlers
             ) {
             }
@@ -766,12 +766,12 @@ iterator, add the ``exclude`` option:
         // src/HandlerCollection.php
         namespace App;
 
-        use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
+        use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
 
         class HandlerCollection
         {
             public function __construct(
-                #[TaggedIterator('app.handler', exclude: ['App\Handler\Three'])]
+                #[AutowireIterator('app.handler', exclude: ['App\Handler\Three'])]
                 iterable $handlers
             ) {
             }
@@ -849,12 +849,12 @@ disabled by setting the ``exclude_self`` option to ``false``:
         // src/HandlerCollection.php
         namespace App;
 
-        use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
+        use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
 
         class HandlerCollection
         {
             public function __construct(
-                #[TaggedIterator('app.handler', exclude: ['App\Handler\Three'], excludeSelf: false)]
+                #[AutowireIterator('app.handler', exclude: ['App\Handler\Three'], excludeSelf: false)]
                 iterable $handlers
             ) {
             }
@@ -999,12 +999,12 @@ you can define it in the configuration of the collecting service:
         // src/HandlerCollection.php
         namespace App;
 
-        use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
+        use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
 
         class HandlerCollection
         {
             public function __construct(
-                #[TaggedIterator('app.handler', defaultPriorityMethod: 'getPriority')]
+                #[AutowireIterator('app.handler', defaultPriorityMethod: 'getPriority')]
                 iterable $handlers
             ) {
             }
@@ -1073,12 +1073,12 @@ to index the services:
         // src/HandlerCollection.php
         namespace App;
 
-        use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
+        use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
 
         class HandlerCollection
         {
             public function __construct(
-                #[TaggedIterator('app.handler', indexAttribute: 'key')]
+                #[AutowireIterator('app.handler', indexAttribute: 'key')]
                 iterable $handlers
             ) {
             }
@@ -1187,12 +1187,12 @@ get the value used to index the services:
         // src/HandlerCollection.php
         namespace App;
 
-        use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
+        use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
 
         class HandlerCollection
         {
             public function __construct(
-                #[TaggedIterator('app.handler', defaultIndexMethod: 'getIndex')]
+                #[AutowireIterator('app.handler', defaultIndexMethod: 'getIndex')]
                 iterable $handlers
             ) {
             }

From 4add5c3a84584eca7fedf90addd32861fef651e7 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Sun, 30 Jun 2024 17:11:46 +0200
Subject: [PATCH 286/747] update Url constraint

---
 reference/constraints/Url.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/reference/constraints/Url.rst b/reference/constraints/Url.rst
index b3a46d5aec4..6e93a284aa7 100644
--- a/reference/constraints/Url.rst
+++ b/reference/constraints/Url.rst
@@ -317,6 +317,11 @@ also relative URLs that contain no protocol (e.g. ``//example.com``).
 
     The ``requiredTld`` option was introduced in Symfony 7.1.
 
+.. deprecated:: 7.1
+
+    Not setting the ``requireTld`` option is deprecated since Symfony 7.1
+    and will default to ``true`` in Symfony 8.0.
+
 By default, URLs like ``https://aaa`` or ``https://foobar`` are considered valid
 because they are tecnically correct according to the `URL spec`_. If you set this option
 to ``true``, the host part of the URL will have to include a TLD (top-level domain

From 4ae71900e4ec8f6f162b8279c5059520c200cb78 Mon Sep 17 00:00:00 2001
From: Hugo Posnic <hugo.posnic@protonmail.com>
Date: Sun, 30 Jun 2024 21:42:49 +0200
Subject: [PATCH 287/747] Update Url.rst

---
 reference/constraints/Url.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/constraints/Url.rst b/reference/constraints/Url.rst
index b3a46d5aec4..f23bbf66a74 100644
--- a/reference/constraints/Url.rst
+++ b/reference/constraints/Url.rst
@@ -315,7 +315,7 @@ also relative URLs that contain no protocol (e.g. ``//example.com``).
 
 .. versionadded:: 7.1
 
-    The ``requiredTld`` option was introduced in Symfony 7.1.
+    The ``requireTld`` option was introduced in Symfony 7.1.
 
 By default, URLs like ``https://aaa`` or ``https://foobar`` are considered valid
 because they are tecnically correct according to the `URL spec`_. If you set this option

From d85d5ee561480163a5cda0d5b31083e15bc68406 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 1 Jul 2024 08:49:09 +0200
Subject: [PATCH 288/747] Minor tweaks

---
 reference/attributes.rst                           |  8 +++-----
 service_container/service_subscribers_locators.rst | 12 ++++--------
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/reference/attributes.rst b/reference/attributes.rst
index ba34afd524d..b1f2f9c5d55 100644
--- a/reference/attributes.rst
+++ b/reference/attributes.rst
@@ -46,11 +46,9 @@ Dependency Injection
 
 .. deprecated:: 7.1
 
-    The
-    :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator`
-    and
-    :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator`
-    were deprecated in Symfony 7.1.
+    The :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator`
+    and :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator`
+    attributes were deprecated in Symfony 7.1.
 
 EventDispatcher
 ~~~~~~~~~~~~~~~
diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst
index 9c36f8c82cd..e040ac2b972 100644
--- a/service_container/service_subscribers_locators.rst
+++ b/service_container/service_subscribers_locators.rst
@@ -309,15 +309,11 @@ This is done by having ``getSubscribedServices()`` return an array of
 
 .. deprecated:: 7.1
 
-    The
-    :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator`
-    and
-    :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator`
-    were deprecated in Symfony 7.1.
+    The :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator`
+    and :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator`
+    attributes were deprecated in Symfony 7.1 in favor of
     :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireIterator`
-    and
-    :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireLocator`
-    should be used instead.
+    and :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireLocator`.
 
 .. note::
 

From b6ffad3ce5e5b558c420f99a5852bd88b5f8ea69 Mon Sep 17 00:00:00 2001
From: Baptiste Leduc <baptiste.leduc@gmail.com>
Date: Wed, 7 Feb 2024 10:11:28 +0100
Subject: [PATCH 289/747] [TypeInfo] Add documentation

---
 components/type_info.rst | 71 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 components/type_info.rst

diff --git a/components/type_info.rst b/components/type_info.rst
new file mode 100644
index 00000000000..12960ff49d2
--- /dev/null
+++ b/components/type_info.rst
@@ -0,0 +1,71 @@
+The TypeInfo Component
+======================
+
+    The TypeInfo component extracts PHP types information. It aims to:
+
+    - Have a powerful Type definition that can handle union, intersections, and generics (and could be even more extended)
+
+    - Being able to get types from anything, such as properties, method arguments, return types, and raw strings (and can also be extended).
+
+.. caution::
+
+    This component is :doc:`experimental </contributing/code/experimental>` and could be changed at any time
+    without prior notice.
+
+Installation
+------------
+
+.. code-block:: terminal
+
+    $ composer require symfony/type-info
+
+.. include:: /components/require_autoload.rst.inc
+
+Usage
+-----
+
+This component will gives you a :class:`Symfony\\Component\\TypeInfo\\Type` object that represents
+the PHP type of whatever you builded or asked to resolve.
+
+There are two ways to use this component. First one is to create a type manually thanks
+to :class:`Symfony\\Component\\TypeInfo\\Type` static methods as following::
+
+    use Symfony\Component\TypeInfo\Type;
+
+    Type::int();
+    Type::nullable(Type::string());
+    Type::generic(Type::object(Collection::class), Type::int());
+    Type::list(Type::bool());
+    Type::intersection(Type::object(\Stringable::class), Type::object(\Iterator::class));
+
+    // Many others are available and can be
+    // found in Symfony\Component\TypeInfo\TypeFactoryTrait
+
+
+Second way to use TypeInfo is to resolve a type based on reflection or a simple string::
+
+    use Symfony\Component\TypeInfo\Type;
+    use Symfony\Component\TypeInfo\TypeResolver\TypeResolver;
+
+    // Instantiate a new resolver
+    $typeResolver = TypeResolver::create();
+
+    // Then resolve types for any subject
+    $typeResolver->resolve(new \ReflectionProperty(Dummy::class, 'id')); // returns an "int" Type instance
+    $typeResolver->resolve('bool'); // returns a "bool" Type instance
+
+    // Types can be instantiated thanks to static factories
+    $type = Type::list(Type::nullable(Type::bool()));
+
+    // Type instances have several helper methods
+    $type->getBaseType() // returns an "array" Type instance
+    $type->getCollectionKeyType(); // returns an "int" Type instance
+    $type->getCollectionValueType()->isNullable(); // returns true
+
+Each of this rows will return you a Type instance that will corresponds to whatever static method you used to build it.
+We also can resolve a type from a string like we can see in this example with the `'bool'` parameter it is mostly
+designed that way so we can give TypeInfo a string from whatever was extracted from existing phpDoc within PropertyInfo.
+
+.. note::
+
+    To support raw string resolving, you need to install ``phpstan/phpdoc-parser`` package.

From 6bb4ae9e19d8a8a7181db4d0d9bbf5815b9553e7 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 2 Jul 2024 16:52:12 +0200
Subject: [PATCH 290/747] Minor rewords

---
 components/type_info.rst | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index 12960ff49d2..f3d1119b1af 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -1,16 +1,20 @@
 The TypeInfo Component
 ======================
 
-    The TypeInfo component extracts PHP types information. It aims to:
+The TypeInfo component extracts type information from PHP elements like properties,
+arguments and return types.
 
-    - Have a powerful Type definition that can handle union, intersections, and generics (and could be even more extended)
+This component provides:
 
-    - Being able to get types from anything, such as properties, method arguments, return types, and raw strings (and can also be extended).
+* A powerful ``Type`` definition that can handle unions, intersections, and generics
+  (and can be extended to support more types in the future);
+* A way to get types from PHP elements such as properties, method arguments,
+  return types, and raw strings.
 
 .. caution::
 
-    This component is :doc:`experimental </contributing/code/experimental>` and could be changed at any time
-    without prior notice.
+    This component is :doc:`experimental </contributing/code/experimental>` and
+    could be changed at any time without prior notice.
 
 Installation
 ------------
@@ -24,11 +28,11 @@ Installation
 Usage
 -----
 
-This component will gives you a :class:`Symfony\\Component\\TypeInfo\\Type` object that represents
-the PHP type of whatever you builded or asked to resolve.
+This component gives you a :class:`Symfony\\Component\\TypeInfo\\Type` object that
+represents the PHP type of anything you built or asked to resolve.
 
 There are two ways to use this component. First one is to create a type manually thanks
-to :class:`Symfony\\Component\\TypeInfo\\Type` static methods as following::
+to the :class:`Symfony\\Component\\TypeInfo\\Type` static methods as following::
 
     use Symfony\Component\TypeInfo\Type;
 
@@ -41,8 +45,8 @@ to :class:`Symfony\\Component\\TypeInfo\\Type` static methods as following::
     // Many others are available and can be
     // found in Symfony\Component\TypeInfo\TypeFactoryTrait
 
-
-Second way to use TypeInfo is to resolve a type based on reflection or a simple string::
+The second way of using the component is to use ``TypeInfo`` to resolve a type
+based on reflection or a simple string::
 
     use Symfony\Component\TypeInfo\Type;
     use Symfony\Component\TypeInfo\TypeResolver\TypeResolver;
@@ -62,9 +66,9 @@ Second way to use TypeInfo is to resolve a type based on reflection or a simple
     $type->getCollectionKeyType(); // returns an "int" Type instance
     $type->getCollectionValueType()->isNullable(); // returns true
 
-Each of this rows will return you a Type instance that will corresponds to whatever static method you used to build it.
-We also can resolve a type from a string like we can see in this example with the `'bool'` parameter it is mostly
-designed that way so we can give TypeInfo a string from whatever was extracted from existing phpDoc within PropertyInfo.
+Each of this calls will return you a ``Type`` instance that corresponds to the
+static method used. You can also resolve types from a string (as shown in the
+``bool`` parameter of the previous example)
 
 .. note::
 

From 8e0643a9c8f7a5608b315245335ef89badee0f60 Mon Sep 17 00:00:00 2001
From: Jacob Dreesen <j.dreesen@neusta.de>
Date: Tue, 2 Jul 2024 17:34:07 +0200
Subject: [PATCH 291/747] Fix typo in the new TypeInfo docs

---
 components/type_info.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index f3d1119b1af..77e25451e6c 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -66,7 +66,7 @@ based on reflection or a simple string::
     $type->getCollectionKeyType(); // returns an "int" Type instance
     $type->getCollectionValueType()->isNullable(); // returns true
 
-Each of this calls will return you a ``Type`` instance that corresponds to the
+Each of these calls will return you a ``Type`` instance that corresponds to the
 static method used. You can also resolve types from a string (as shown in the
 ``bool`` parameter of the previous example)
 

From 09e7fab9107d5bd8d001598b9b7fdd7754f1d397 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 3 Jul 2024 09:27:30 +0200
Subject: [PATCH 292/747] [TypeInfo] Better explain the getBaseType() method

---
 components/type_info.rst | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index 77e25451e6c..1c42a89b3c8 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -62,9 +62,20 @@ based on reflection or a simple string::
     $type = Type::list(Type::nullable(Type::bool()));
 
     // Type instances have several helper methods
-    $type->getBaseType() // returns an "array" Type instance
-    $type->getCollectionKeyType(); // returns an "int" Type instance
-    $type->getCollectionValueType()->isNullable(); // returns true
+
+    // returns the main type (e.g. in this example ir returns an "array" Type instance)
+    // for nullable types (e.g. string|null) returns the non-null type (e.g. string)
+    // and for compound types (e.g. int|string) it throws an exception because both types
+    // can be considered the main one, so there's no way to pick one
+    $baseType = $type->getBaseType();
+
+    // for collections, it returns the type of the item used as the key
+    // in this example, the collection is a list, so it returns and "int" Type instance
+    $keyType = $type->getCollectionKeyType();
+
+    // you can chain the utility methods e.g. to introspect the values of the collection
+    // the following code will return true
+    $isValueNullable = $type->getCollectionValueType()->isNullable();
 
 Each of these calls will return you a ``Type`` instance that corresponds to the
 static method used. You can also resolve types from a string (as shown in the

From c4e8ace5ce8e095c4c6a67a1db20d979a003195b Mon Sep 17 00:00:00 2001
From: sakul95 <60596924+sakul95@users.noreply.github.com>
Date: Wed, 3 Jul 2024 10:10:25 +0200
Subject: [PATCH 293/747] [Notifier] Add Sipgate bridge

---
 notifier.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/notifier.rst b/notifier.rst
index 1a19c135a7c..3ecb8878fb4 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -159,6 +159,9 @@ Service
 `Sinch`_            **Install**: ``composer require symfony/sinch-notifier`` \
                     **DSN**: ``sinch://ACCOUNT_ID:AUTH_TOKEN@default?from=FROM`` \
                     **Webhook support**: No
+`Sipgate`_          **Install**: ``composer require symfony/sipgate-notifier`` \
+                    **DSN**: ``sipgate://TOKEN_ID:TOKEN@default?senderId=SENDER_ID`` \
+                    **Webhook support**: No
 `SmsSluzba`_        **Install**: ``composer require symfony/sms-sluzba-notifier`` \
                     **DSN**: ``sms-sluzba://USERNAME:PASSWORD@default`` \
                     **Webhook support**: No
@@ -214,6 +217,10 @@ Service
     The ``Smsbox``, ``SmsSluzba``, ``SMSense``, ``LOX24`` and ``Unifonic``
     integrations were introduced in Symfony 7.1.
 
+.. versionadded:: 7.2
+
+    The ``Sipgate`` integration was introduced in Symfony 7.2.
+
 .. deprecated:: 7.1
 
     The `Sms77`_ integration is deprecated since
@@ -1131,6 +1138,7 @@ is dispatched. Listeners receive a
 .. _`Seven.io`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sevenio/README.md
 .. _`SimpleTextin`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SimpleTextin/README.md
 .. _`Sinch`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sinch/README.md
+.. _`Sipgate`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sipgate/README.md
 .. _`Slack`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Slack/README.md
 .. _`Sms77`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sms77/README.md
 .. _`SmsBiuras`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SmsBiuras/README.md

From 9f4e5a5fb5418489978f0b30e5803e4eaec80baf Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Sun, 7 Jul 2024 13:56:54 +0200
Subject: [PATCH 294/747] Remove the Gitter bridge

---
 notifier.rst | 2 --
 1 file changed, 2 deletions(-)

diff --git a/notifier.rst b/notifier.rst
index 5fe86724fe1..cbc23655124 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -351,7 +351,6 @@ Service                                  Package                               D
 `Discord`_                               ``symfony/discord-notifier``          ``discord://TOKEN@default?webhook_id=ID``
 `FakeChat`_                              ``symfony/fake-chat-notifier``        ``fakechat+email://default?to=TO&from=FROM`` or ``fakechat+logger://default``
 `Firebase`_                              ``symfony/firebase-notifier``         ``firebase://USERNAME:PASSWORD@default``
-`Gitter`_                                ``symfony/gitter-notifier``           ``gitter://TOKEN@default?room_id=ROOM_ID``
 `GoogleChat`_                            ``symfony/google-chat-notifier``      ``googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?thread_key=THREAD_KEY``
 `LINE Notify`_                           ``symfony/line-notify-notifier``      ``linenotify://TOKEN@default``
 `LinkedIn`_                              ``symfony/linked-in-notifier``        ``linkedin://TOKEN:USER_ID@default``
@@ -1105,7 +1104,6 @@ is dispatched. Listeners receive a
 .. _`Firebase`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Firebase/README.md
 .. _`FreeMobile`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/FreeMobile/README.md
 .. _`GatewayApi`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/GatewayApi/README.md
-.. _`Gitter`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Gitter/README.md
 .. _`GoIP`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/GoIP/README.md
 .. _`GoogleChat`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/GoogleChat/README.md
 .. _`Infobip`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Infobip/README.md

From 03173f88b1d74cb64a5ae1042bbdd19a3d515531 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 8 Jul 2024 09:39:04 +0200
Subject: [PATCH 295/747] Add a note explaining the removal of Gitter

---
 notifier.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/notifier.rst b/notifier.rst
index cbc23655124..d959b4a73d0 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -370,6 +370,11 @@ Service                                  Package                               D
 
     The ``Bluesky`` integration was introduced in Symfony 7.1.
 
+.. deprecated:: 7.2
+
+    The ``Gitter`` integration was removed in Symfony 7.2 because that service
+    no longer provides an API.
+
 .. caution::
 
     By default, if you have the :doc:`Messenger component </messenger>` installed,

From 15a50b58980903c362e534d21021cfc88c0d72d6 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 8 Jul 2024 10:34:38 +0200
Subject: [PATCH 296/747] Minor tweaks

---
 components/type_info.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index 1c42a89b3c8..f6b5e84a0f5 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -63,17 +63,17 @@ based on reflection or a simple string::
 
     // Type instances have several helper methods
 
-    // returns the main type (e.g. in this example ir returns an "array" Type instance)
-    // for nullable types (e.g. string|null) returns the non-null type (e.g. string)
+    // returns the main type (e.g. in this example i returns an "array" Type instance);
+    // for nullable types (e.g. string|null) it returns the non-null type (e.g. string)
     // and for compound types (e.g. int|string) it throws an exception because both types
     // can be considered the main one, so there's no way to pick one
     $baseType = $type->getBaseType();
 
-    // for collections, it returns the type of the item used as the key
+    // for collections, it returns the type of the item used as the key;
     // in this example, the collection is a list, so it returns and "int" Type instance
     $keyType = $type->getCollectionKeyType();
 
-    // you can chain the utility methods e.g. to introspect the values of the collection
+    // you can chain the utility methods (e.g. to introspect the values of the collection)
     // the following code will return true
     $isValueNullable = $type->getCollectionValueType()->isNullable();
 

From 7928e4d7b21c7e860492c7ee6e9dbcd4a1f2e1ef Mon Sep 17 00:00:00 2001
From: Tim Herlaud <therlaud@interdrinks.fr>
Date: Wed, 10 Jul 2024 09:17:34 +0200
Subject: [PATCH 297/747] [String] Add TruncateMode mode to truncate methods

---
 string.rst | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/string.rst b/string.rst
index c58a736da89..c956d33b9af 100644
--- a/string.rst
+++ b/string.rst
@@ -394,11 +394,16 @@ Methods to Join, Split, Truncate and Reverse
     u('Lorem Ipsum')->truncate(3);             // 'Lor'
     u('Lorem Ipsum')->truncate(80);            // 'Lorem Ipsum'
     // the second argument is the character(s) added when a string is cut
+    // the third argument is TruncateMode::Char by default
     // (the total length includes the length of this character(s))
-    u('Lorem Ipsum')->truncate(8, '…');             // 'Lorem I…'
-    // if the third argument is false, the last word before the cut is kept
-    // even if that generates a string longer than the desired length
-    u('Lorem Ipsum')->truncate(8, '…', cut: false); // 'Lorem Ipsum'
+    u('Lorem Ipsum')->truncate(8, '…');        // 'Lorem I…'
+    // use options to keep complete words
+    u('Lorem ipsum dolor sit amet')->truncate(10, '...', TruncateMode::WordBefore);  // 'Lorem...'
+    u('Lorem ipsum dolor sit amet')->truncate(14, '...', TruncateMode::WordAfter);  // 'Lorem ipsum...'
+
+.. versionadded:: 7.2
+
+    The TruncateMode argument for truncate function was introduced in Symfony 7.2.
 
 ::
 

From b607d25adaad279a4c0b974713f3f627c00cff7c Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 10 Jul 2024 17:09:38 +0200
Subject: [PATCH 298/747] Reword

---
 string.rst | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/string.rst b/string.rst
index 72dfb5c4ae7..cd104b1f947 100644
--- a/string.rst
+++ b/string.rst
@@ -394,16 +394,20 @@ Methods to Join, Split, Truncate and Reverse
     u('Lorem Ipsum')->truncate(3);             // 'Lor'
     u('Lorem Ipsum')->truncate(80);            // 'Lorem Ipsum'
     // the second argument is the character(s) added when a string is cut
-    // the third argument is TruncateMode::Char by default
     // (the total length includes the length of this character(s))
+    // (note that '…' is a single character that includes three dots; it's not '...')
     u('Lorem Ipsum')->truncate(8, '…');        // 'Lorem I…'
-    // use options to keep complete words
-    u('Lorem ipsum dolor sit amet')->truncate(10, '...', TruncateMode::WordBefore);  // 'Lorem...'
-    u('Lorem ipsum dolor sit amet')->truncate(14, '...', TruncateMode::WordAfter);  // 'Lorem ipsum...'
+    // the third optional argument defines how to cut words when the length is exceeded
+    // the default value is TruncateMode::Char which cuts the string at the exact given length
+    u('Lorem ipsum dolor sit amet')->truncate(8, cut: TruncateMode::Char);       // 'Lorem ip'
+    // returns up to the last complete word that fits in the given length without surpassing it
+    u('Lorem ipsum dolor sit amet')->truncate(8, cut: TruncateMode::WordBefore); // 'Lorem'
+    // returns up to the last complete word that fits in the given length, surpassing it if needed
+    u('Lorem ipsum dolor sit amet')->truncate(8, cut: TruncateMode::WordAfter);   // 'Lorem ipsum'
 
 .. versionadded:: 7.2
 
-    The TruncateMode argument for truncate function was introduced in Symfony 7.2.
+    The ``TruncateMode`` argument for truncate function was introduced in Symfony 7.2.
 
 ::
 

From 3236182336c79d9d3ea5a28a2c21550067b636a0 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Wed, 10 Jul 2024 20:06:51 +0200
Subject: [PATCH 299/747] -

---
 string.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/string.rst b/string.rst
index cd104b1f947..f2856976986 100644
--- a/string.rst
+++ b/string.rst
@@ -407,7 +407,7 @@ Methods to Join, Split, Truncate and Reverse
 
 .. versionadded:: 7.2
 
-    The ``TruncateMode`` argument for truncate function was introduced in Symfony 7.2.
+    The ``TruncateMode`` parameter for truncate function was introduced in Symfony 7.2.
 
 ::
 

From e983455bc391256a77f5397efe650393e9c58c04 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 17 Jul 2024 15:13:29 +0200
Subject: [PATCH 300/747] [Validator] Add the `WordCount` constraint

---
 reference/constraints/WordCount.rst | 150 ++++++++++++++++++++++++++++
 reference/constraints/map.rst.inc   |   1 +
 2 files changed, 151 insertions(+)
 create mode 100644 reference/constraints/WordCount.rst

diff --git a/reference/constraints/WordCount.rst b/reference/constraints/WordCount.rst
new file mode 100644
index 00000000000..74c79216898
--- /dev/null
+++ b/reference/constraints/WordCount.rst
@@ -0,0 +1,150 @@
+WordCount
+=========
+
+.. versionadded:: 7.2
+
+    The ``WordCount`` constraint was introduced in Symfony 7.2.
+
+Validates that a string (or an object implementing the ``Stringable`` PHP interface)
+contains a given number of words. Internally, this constraint uses the
+:phpclass:`IntlBreakIterator` class to count the words depending on your locale.
+
+==========  =======================================================================
+Applies to  :ref:`property or method <validation-property-target>`
+Class       :class:`Symfony\\Component\\Validator\\Constraints\\WordCount`
+Validator   :class:`Symfony\\Component\\Validator\\Constraints\\WordCountValidator`
+==========  =======================================================================
+
+Basic Usage
+-----------
+
+If you wanted to ensure that the ``content`` property of a ``BlogPostDTO``
+class contains between 100 and 200 words, you could do the following:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Entity/BlogPostDTO.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+
+        class BlogPostDTO
+        {
+            #[Assert\WordCount(min: 100, max: 200)]
+            protected string $content;
+        }
+
+    .. code-block:: yaml
+
+        # config/validator/validation.yaml
+        App\Entity\BlogPostDTO:
+            properties:
+                content:
+                    - WordCount:
+                        min: 100
+                        max: 200
+
+    .. code-block:: xml
+
+        <!-- config/validator/validation.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
+
+            <class name="App\Entity\BlogPostDTO">
+                <property name="content">
+                    <constraint name="WordCount">
+                        <option name="min">100</option>
+                        <option name="max">200</option>
+                    </constraint>
+                </property>
+            </class>
+        </constraint-mapping>
+
+    .. code-block:: php
+
+        // src/Entity/BlogPostDTO.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+        use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+        class BlogPostDTO
+        {
+            // ...
+
+            public static function loadValidatorMetadata(ClassMetadata $metadata): void
+            {
+                $metadata->addPropertyConstraint('content', new Assert\WordCount([
+                    'min' => 100,
+                    'max' => 200,
+                ]));
+            }
+        }
+
+Options
+-------
+
+``min``
+~~~~~~~
+
+**type**: ``integer`` **default**: ``null``
+
+The minimum number of words that the value must contain.
+
+``max``
+~~~~~~~
+
+**type**: ``integer`` **default**: ``null``
+
+The maximum number of words that the value must contain.
+
+``locale``
+~~~~~~~~~~
+
+**type**: ``string`` **default**: ``null``
+
+The locale to use for counting the words by using the :phpclass:`IntlBreakIterator`
+class. The default value (``null``) means that the constraint uses the current
+user locale.
+
+.. include:: /reference/constraints/_groups-option.rst.inc
+
+``minMessage``
+~~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``This value is too short. It should contain at least one word.|This value is too short. It should contain at least {{ min }} words.``
+
+This is the message that will be shown if the value does not contain at least
+the minimum number of words.
+
+You can use the following parameters in this message:
+
+================  ==================================================
+Parameter         Description
+================  ==================================================
+``{{ min }}``     The minimum number of words
+``{{ count }}``   The actual number of words
+================  ==================================================
+
+``maxMessage``
+~~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``This value is too long. It should contain one word.|This value is too long. It should contain {{ max }} words or less.``
+
+This is the message that will be shown if the value contains more than the
+maximum number of words.
+
+You can use the following parameters in this message:
+
+================  ==================================================
+Parameter         Description
+================  ==================================================
+``{{ max }}``     The maximum number of words
+``{{ count }}``   The actual number of words
+================  ==================================================
+
+.. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/map.rst.inc b/reference/constraints/map.rst.inc
index 9f14f418bb1..978951c9de7 100644
--- a/reference/constraints/map.rst.inc
+++ b/reference/constraints/map.rst.inc
@@ -33,6 +33,7 @@ String Constraints
 * :doc:`NoSuspiciousCharacters </reference/constraints/NoSuspiciousCharacters>`
 * :doc:`Charset </reference/constraints/Charset>`
 * :doc:`MacAddress </reference/constraints/MacAddress>`
+* :doc:`WordCount </reference/constraints/WordCount>`
 
 Comparison Constraints
 ~~~~~~~~~~~~~~~~~~~~~~

From 47279ab422ce618a328db6f7ba96cc2efa80ad93 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Fri, 19 Jul 2024 12:12:22 +0200
Subject: [PATCH 301/747] fix typos

---
 components/type_info.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index f6b5e84a0f5..30ae11aa222 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -63,14 +63,14 @@ based on reflection or a simple string::
 
     // Type instances have several helper methods
 
-    // returns the main type (e.g. in this example i returns an "array" Type instance);
+    // returns the main type (e.g. in this example it returns an "array" Type instance);
     // for nullable types (e.g. string|null) it returns the non-null type (e.g. string)
     // and for compound types (e.g. int|string) it throws an exception because both types
     // can be considered the main one, so there's no way to pick one
     $baseType = $type->getBaseType();
 
     // for collections, it returns the type of the item used as the key;
-    // in this example, the collection is a list, so it returns and "int" Type instance
+    // in this example, the collection is a list, so it returns an "int" Type instance
     $keyType = $type->getCollectionKeyType();
 
     // you can chain the utility methods (e.g. to introspect the values of the collection)

From 16c9fdb2b0ea5b647cdb1f7904d85b67f983beef Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Fri, 19 Jul 2024 12:47:06 +0200
Subject: [PATCH 302/747] use the ref role for internal links

---
 reference/events.rst | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/reference/events.rst b/reference/events.rst
index 411e5e327f5..57806ee8f8d 100644
--- a/reference/events.rst
+++ b/reference/events.rst
@@ -56,8 +56,8 @@ their priorities:
 
 This event is dispatched after the controller has been resolved but before executing
 it. It's useful to initialize things later needed by the
-controller, such as `value resolvers`_, and even to change the controller
-entirely::
+controller, such as :ref:`value resolvers <managing-value-resolvers>`, and
+even to change the controller entirely::
 
     use Symfony\Component\HttpKernel\Event\ControllerEvent;
 
@@ -296,5 +296,3 @@ their priorities:
 .. code-block:: terminal
 
     $ php bin/console debug:event-dispatcher kernel.exception
-
-.. _`value resolvers`: https://symfony.com/doc/current/controller/value_resolver.html#managing-value-resolvers

From fa572ee1d7fd2cea6717ab3a52a93d30d536c04b Mon Sep 17 00:00:00 2001
From: Petrisor Ciprian Daniel <dciprian.petrisor@gmail.com>
Date: Fri, 19 Jul 2024 23:31:27 +0300
Subject: [PATCH 303/747] [Config] Secrets decrypt exit option

---
 configuration/secrets.rst | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/configuration/secrets.rst b/configuration/secrets.rst
index f717456a22c..b16c36643aa 100644
--- a/configuration/secrets.rst
+++ b/configuration/secrets.rst
@@ -271,11 +271,20 @@ manually store this file somewhere and deploy it. There are 2 ways to do that:
 
    .. code-block:: terminal
 
-       $ APP_RUNTIME_ENV=prod php bin/console secrets:decrypt-to-local --force
+       $ APP_RUNTIME_ENV=prod php bin/console secrets:decrypt-to-local --force --exit
 
    This will write all the decrypted secrets into the ``.env.prod.local`` file.
    After doing this, the decryption key does *not* need to remain on the server(s).
 
+   Note the usage of the ``--exit`` option: this forces all secrets to be successfully
+   decrypted, otherwise a non-zero exit code is returned.
+
+   If you wish to continue regardless of errors occurring during decryption, you may omit this option.
+
+   .. versionadded:: 7.2
+
+    The ``--exit`` option was introduced in Symfony 7.2.
+
 Rotating Secrets
 ----------------
 

From 97103298ebabb6f3fb5c015450e1d8f893149bca Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 22 Jul 2024 09:03:49 +0200
Subject: [PATCH 304/747] Tweaks

---
 configuration/secrets.rst | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/configuration/secrets.rst b/configuration/secrets.rst
index b16c36643aa..734873b255c 100644
--- a/configuration/secrets.rst
+++ b/configuration/secrets.rst
@@ -276,14 +276,16 @@ manually store this file somewhere and deploy it. There are 2 ways to do that:
    This will write all the decrypted secrets into the ``.env.prod.local`` file.
    After doing this, the decryption key does *not* need to remain on the server(s).
 
-   Note the usage of the ``--exit`` option: this forces all secrets to be successfully
-   decrypted, otherwise a non-zero exit code is returned.
+   Note the usage of the ``--exit`` option: this ensures that all secrets are
+   successfully decrypted. If any error occurs during the decryption process,
+   the command will return a non-zero exit code, indicating a failure.
 
-   If you wish to continue regardless of errors occurring during decryption, you may omit this option.
+   If you wish to continue regardless of errors occurring during decryption,
+   you may omit this option.
 
    .. versionadded:: 7.2
 
-    The ``--exit`` option was introduced in Symfony 7.2.
+       The ``--exit`` option was introduced in Symfony 7.2.
 
 Rotating Secrets
 ----------------

From 8e1d67b18758832865b51fd28066018cfc34b9ac Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Mon, 22 Jul 2024 15:16:47 +0200
Subject: [PATCH 305/747] drop the --exit option

---
 configuration/secrets.rst | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/configuration/secrets.rst b/configuration/secrets.rst
index 734873b255c..f717456a22c 100644
--- a/configuration/secrets.rst
+++ b/configuration/secrets.rst
@@ -271,22 +271,11 @@ manually store this file somewhere and deploy it. There are 2 ways to do that:
 
    .. code-block:: terminal
 
-       $ APP_RUNTIME_ENV=prod php bin/console secrets:decrypt-to-local --force --exit
+       $ APP_RUNTIME_ENV=prod php bin/console secrets:decrypt-to-local --force
 
    This will write all the decrypted secrets into the ``.env.prod.local`` file.
    After doing this, the decryption key does *not* need to remain on the server(s).
 
-   Note the usage of the ``--exit`` option: this ensures that all secrets are
-   successfully decrypted. If any error occurs during the decryption process,
-   the command will return a non-zero exit code, indicating a failure.
-
-   If you wish to continue regardless of errors occurring during decryption,
-   you may omit this option.
-
-   .. versionadded:: 7.2
-
-       The ``--exit`` option was introduced in Symfony 7.2.
-
 Rotating Secrets
 ----------------
 

From f5f16af36ded58edf37af2be3fe6f078d7c6b64b Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Thu, 25 Jul 2024 09:54:38 +0200
Subject: [PATCH 306/747] add the $token argument to checkPostAuth()

---
 security/user_checkers.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/security/user_checkers.rst b/security/user_checkers.rst
index d62cc0bea32..1e1dcaf3e55 100644
--- a/security/user_checkers.rst
+++ b/security/user_checkers.rst
@@ -40,7 +40,7 @@ displayed to the user::
             }
         }
 
-        public function checkPostAuth(UserInterface $user): void
+        public function checkPostAuth(UserInterface $user, TokenInterface $token): void
         {
             if (!$user instanceof AppUser) {
                 return;

From aec2ec5ef61cca979c9d830a6fd22d6a64446ab4 Mon Sep 17 00:00:00 2001
From: Marcin Nowak <kontakt@nowak-marcin.pl>
Date: Fri, 26 Jul 2024 14:12:16 +0200
Subject: [PATCH 307/747] Added information about clock parameter in
 ArrayAdapter

---
 components/cache/adapters/array_cache_adapter.rst | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/components/cache/adapters/array_cache_adapter.rst b/components/cache/adapters/array_cache_adapter.rst
index f903771e468..a6a72514361 100644
--- a/components/cache/adapters/array_cache_adapter.rst
+++ b/components/cache/adapters/array_cache_adapter.rst
@@ -24,5 +24,10 @@ method::
 
         // the maximum number of items that can be stored in the cache. When the limit
         // is reached, cache follows the LRU model (least recently used items are deleted)
-        $maxItems = 0
+        $maxItems = 0,
+
+        // implementation of Psr\Clock\ClockInterface (e.g. Symfony\Component\Clock\Clock)
+        // or null. If clock is provided, cache items lifetime will be calculated
+        // based on time provided by this clock
+        $clock = null
     );

From 87acbbcce5954cd05f16824d8db91b42fe954318 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Fri, 26 Jul 2024 14:29:19 +0200
Subject: [PATCH 308/747] fix the syntax of PHP code blocks

---
 configuration/micro_kernel_trait.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/configuration/micro_kernel_trait.rst b/configuration/micro_kernel_trait.rst
index 23aa677cf20..c9739679f69 100644
--- a/configuration/micro_kernel_trait.rst
+++ b/configuration/micro_kernel_trait.rst
@@ -57,7 +57,7 @@ Next, create an ``index.php`` file that defines the kernel class and runs it:
 
         return static function (array $context) {
             return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
-        }
+        };
 
     .. code-block:: php
 
@@ -98,7 +98,7 @@ Next, create an ``index.php`` file that defines the kernel class and runs it:
 
         return static function (array $context) {
             return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
-        }
+        };
 
 That's it! To test it, start the :doc:`Symfony Local Web Server
 </setup/symfony_server>`:

From f1c8808ee481a65b1e10453e362b54b98c3ae4cc Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 26 Jul 2024 17:03:46 +0200
Subject: [PATCH 309/747] [Cache] Igbinary extension is no longer used by
 default when available

---
 components/cache.rst | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/components/cache.rst b/components/cache.rst
index f5a76f2119d..939627b1807 100644
--- a/components/cache.rst
+++ b/components/cache.rst
@@ -208,16 +208,27 @@ Symfony uses *marshallers* (classes which implement
 the cache items before storing them.
 
 The :class:`Symfony\\Component\\Cache\\Marshaller\\DefaultMarshaller` uses PHP's
-``serialize()`` or ``igbinary_serialize()`` if the `Igbinary extension`_ is installed.
-There are other *marshallers* that can encrypt or compress the data before storing it::
+``serialize()`` function by default, but you can optionally use the ``igbinary_serialize()``
+function from the `Igbinary extension`_:
 
     use Symfony\Component\Cache\Adapter\RedisAdapter;
     use Symfony\Component\Cache\DefaultMarshaller;
     use Symfony\Component\Cache\DeflateMarshaller;
 
     $marshaller = new DeflateMarshaller(new DefaultMarshaller());
+    // you can optionally use the Igbinary extension if you have it installed
+    // $marshaller = new DeflateMarshaller(new DefaultMarshaller(useIgbinarySerialize: true));
+
     $cache = new RedisAdapter(new \Redis(), 'namespace', 0, $marshaller);
 
+There are other *marshallers* that can encrypt or compress the data before storing it.
+
+.. versionadded:: 7.2
+
+    In Symfony versions prior to 7.2, the ``igbinary_serialize()`` function was
+    used by default when the Igbinary extension was installed. Starting from
+    Symfony 7.2, you have to enable Igbinary support explicitly.
+
 Advanced Usage
 --------------
 

From d2b384beacf7a749ffaf0e98b9f41315a95893a2 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Tue, 30 Jul 2024 16:38:51 +0200
Subject: [PATCH 310/747] fix typo

---
 performance.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/performance.rst b/performance.rst
index 70a6602873e..828333f338b 100644
--- a/performance.rst
+++ b/performance.rst
@@ -367,7 +367,7 @@ method does, which stops an event and then restarts it immediately::
 
 .. versionadded:: 7.2
 
-    The ``getLastPeriod`` method was introduced in Symfony 7.2.
+    The ``getLastPeriod()`` method was introduced in Symfony 7.2.
 
 Profiling Sections
 ..................

From e2d8f0a36494d6370e0c845a18a36a84f8329ea5 Mon Sep 17 00:00:00 2001
From: Jonas Claes <jonas@jonasclaes.be>
Date: Thu, 1 Aug 2024 19:31:56 +0200
Subject: [PATCH 311/747] Update mailer.rst

---
 mailer.rst | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/mailer.rst b/mailer.rst
index 502644a741a..11acd065e52 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -110,6 +110,7 @@ Service               Install with                                    Webhook su
 `MailPace`_           ``composer require symfony/mail-pace-mailer``
 `MailerSend`_         ``composer require symfony/mailer-send-mailer``
 `Mandrill`_           ``composer require symfony/mailchimp-mailer``
+`Postal`_             ``composer require symfony/postal-mailer``
 `Postmark`_           ``composer require symfony/postmark-mailer``    yes
 `Resend`_             ``composer require symfony/resend-mailer``      yes
 `Scaleway`_           ``composer require symfony/scaleway-mailer``
@@ -122,7 +123,7 @@ Service               Install with                                    Webhook su
 
 .. versionadded:: 7.2
 
-    The Mailomat integration was introduced in Symfony 7.2.
+    The Mailomat and Postal integrations were introduced in Symfony 7.2.
 
 .. note::
 
@@ -214,6 +215,10 @@ party provider:
 |                        | - HTTP n/a                                              |
 |                        | - API ``mailpace+api://API_TOKEN@default``              |
 +------------------------+---------------------------------------------------------+
+| `Postal`_              | - SMTP n/a                                              |
+|                        | - HTTP n/a                                              |
+|                        | - API ``postal+api://API_KEY@BASE_URL``                 |
++------------------------+---------------------------------------------------------+
 | `Postmark`_            | - SMTP ``postmark+smtp://ID@default``                   |
 |                        | - HTTP n/a                                              |
 |                        | - API ``postmark+api://KEY@default``                    |
@@ -1992,6 +1997,7 @@ the :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\MailerAssertionsTrait`::
 .. _`MailPace`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/MailPace/README.md
 .. _`OpenSSL PHP extension`: https://www.php.net/manual/en/book.openssl.php
 .. _`PEM encoded`: https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail
+.. _`Postal`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Postal/README.md
 .. _`Postmark`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Postmark/README.md
 .. _`Resend`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Resend/README.md
 .. _`RFC 3986`: https://www.ietf.org/rfc/rfc3986.txt

From 4b3fad09b8894e9d61876e1fdd8752275fe57691 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 6 Aug 2024 17:44:01 +0200
Subject: [PATCH 312/747] Add the versionadded directive

---
 components/cache/adapters/array_cache_adapter.rst | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/components/cache/adapters/array_cache_adapter.rst b/components/cache/adapters/array_cache_adapter.rst
index a6a72514361..08f8276db3d 100644
--- a/components/cache/adapters/array_cache_adapter.rst
+++ b/components/cache/adapters/array_cache_adapter.rst
@@ -26,8 +26,12 @@ method::
         // is reached, cache follows the LRU model (least recently used items are deleted)
         $maxItems = 0,
 
-        // implementation of Psr\Clock\ClockInterface (e.g. Symfony\Component\Clock\Clock)
-        // or null. If clock is provided, cache items lifetime will be calculated
-        // based on time provided by this clock
-        $clock = null
+        // optional implementation of the Psr\Clock\ClockInterface that will be used
+        // to calculate the lifetime of cache items (for example to get predictable
+        // lifetimes in tests)
+        $clock = null,
     );
+
+.. versionadded:: 7.2
+
+    The optional ``$clock`` argument was introduced in Symfony 7.2.

From c7bf80275b6a65807642e860fc19af77ffd6c453 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 7 Aug 2024 11:02:10 +0200
Subject: [PATCH 313/747] [Validator] Mention `Ulid::FORMAT_RFC4122`

---
 reference/constraints/Ulid.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/reference/constraints/Ulid.rst b/reference/constraints/Ulid.rst
index 4ba5ec3a3f5..a5888409960 100644
--- a/reference/constraints/Ulid.rst
+++ b/reference/constraints/Ulid.rst
@@ -82,6 +82,7 @@ The format of the ULID to validate. The following formats are available:
 
 * ``Ulid::FORMAT_BASE_32``: The ULID is encoded in base32 (default)
 * ``Ulid::FORMAT_BASE_58``: The ULID is encoded in base58
+* ``Ulid::FORMAT_RFC4122``: The ULID is encoded in the RFC 4122 format
 
 .. versionadded:: 7.2
 

From 9381f4be9bf1149ab63d850b84d678e2e1df6869 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 7 Aug 2024 14:20:31 +0200
Subject: [PATCH 314/747] [Validator] Add links to Ulid constraint formats

---
 reference/constraints/Ulid.rst | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/reference/constraints/Ulid.rst b/reference/constraints/Ulid.rst
index a5888409960..4094bab98f5 100644
--- a/reference/constraints/Ulid.rst
+++ b/reference/constraints/Ulid.rst
@@ -80,9 +80,9 @@ Options
 
 The format of the ULID to validate. The following formats are available:
 
-* ``Ulid::FORMAT_BASE_32``: The ULID is encoded in base32 (default)
-* ``Ulid::FORMAT_BASE_58``: The ULID is encoded in base58
-* ``Ulid::FORMAT_RFC4122``: The ULID is encoded in the RFC 4122 format
+* ``Ulid::FORMAT_BASE_32``: The ULID is encoded in `base32`_ (default)
+* ``Ulid::FORMAT_BASE_58``: The ULID is encoded in `base58`_
+* ``Ulid::FORMAT_RFC4122``: The ULID is encoded in the `RFC 4122 format`_
 
 .. versionadded:: 7.2
 
@@ -111,3 +111,6 @@ Parameter        Description
 .. include:: /reference/constraints/_payload-option.rst.inc
 
 .. _`Universally Unique Lexicographically Sortable Identifier (ULID)`: https://github.com/ulid/spec
+.. _`base32`: https://en.wikipedia.org/wiki/Base32
+.. _`base58`: https://en.wikipedia.org/wiki/Binary-to-text_encoding#Base58
+.. _`RFC 4122 format`: https://datatracker.ietf.org/doc/html/rfc4122

From ce138921bd92a98340ed20ba16b6ebe0520d3ef4 Mon Sep 17 00:00:00 2001
From: Philippe Chabbert <chab.philippe@gmail.com>
Date: Thu, 8 Aug 2024 11:42:42 +0200
Subject: [PATCH 315/747] doc: add missing use statements

---
 configuration/multiple_kernels.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/configuration/multiple_kernels.rst b/configuration/multiple_kernels.rst
index 4cef8b0d09e..512ea57f24d 100644
--- a/configuration/multiple_kernels.rst
+++ b/configuration/multiple_kernels.rst
@@ -117,7 +117,9 @@ resources::
     // src/Kernel.php
     namespace Shared;
 
+    use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
     use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
+    use Symfony\Component\HttpKernel\Kernel as BaseKernel;
     use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
 
     class Kernel extends BaseKernel
@@ -258,6 +260,7 @@ the application ID to run under CLI context::
 
     // bin/console
     use Shared\Kernel;
+    use Symfony\Bundle\FrameworkBundle\Console\Application;
     use Symfony\Component\Console\Input\InputInterface;
     use Symfony\Component\Console\Input\InputOption;
 

From ed5124230a9e8bdacad8c9ab7459f0e2785e281a Mon Sep 17 00:00:00 2001
From: n-valverde <64469669+n-valverde@users.noreply.github.com>
Date: Sat, 17 Feb 2024 10:52:22 +0100
Subject: [PATCH 316/747] Update service_container.rst

---
 service_container.rst | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/service_container.rst b/service_container.rst
index 569f549990b..1afc59189ed 100644
--- a/service_container.rst
+++ b/service_container.rst
@@ -1035,20 +1035,25 @@ to them.
 Linting Service Definitions
 ---------------------------
 
-The ``lint:container`` command checks that the arguments injected into services
-match their type declarations. It's useful to run it before deploying your
-application to production (e.g. in your continuous integration server):
+The ``lint:container`` command performs some additional checks to make sure
+the container is properly configured:
+* ensures the arguments injected into services match their type declarations.
+* ensures the interfaces configured as alias are resolving to a compatible
+service.
+It's useful to run it before deploying your application to production
+(e.g. in your continuous integration server):
 
 .. code-block:: terminal
 
     $ php bin/console lint:container
 
-Checking the types of all service arguments whenever the container is compiled
-can hurt performance. That's why this type checking is implemented in a
-:doc:`compiler pass </service_container/compiler_passes>` called
-``CheckTypeDeclarationsPass`` which is disabled by default and enabled only when
-executing the ``lint:container`` command. If you don't mind the performance
-loss, enable the compiler pass in your application.
+Doing those checks whenever the container is compiled
+can hurt performance. That's why this is implemented in
+:doc:`compiler passes </service_container/compiler_passes>` called
+``CheckTypeDeclarationsPass`` and ``CheckAliasValidityPass`` which are disabled
+by default and enabled only when executing the ``lint:container`` command.
+If you don't mind the performance loss, enable these compiler passes in
+your application.
 
 .. _container-public:
 

From e2a15ae1c200ad097f9fb246c0eda5ade815304d Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 9 Aug 2024 16:39:28 +0200
Subject: [PATCH 317/747] Minor tweaks

---
 service_container.rst | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/service_container.rst b/service_container.rst
index aa7868cfdd7..b5d3f8c5b99 100644
--- a/service_container.rst
+++ b/service_container.rst
@@ -1035,26 +1035,25 @@ to them.
 Linting Service Definitions
 ---------------------------
 
-The ``lint:container`` command performs some additional checks to make sure
-the container is properly configured:
-* ensures the arguments injected into services match their type declarations.
-* ensures the interfaces configured as alias are resolving to a compatible
-service.
-It's useful to run it before deploying your application to production
-(e.g. in your continuous integration server):
+The ``lint:container`` command performs additional checks to ensure the container
+is properly configured. It is useful to run this command before deploying your
+application to production (e.g. in your continuous integration server):
 
 .. code-block:: terminal
 
     $ php bin/console lint:container
 
-Doing those checks whenever the container is compiled
-can hurt performance. That's why this is implemented in
-:doc:`compiler passes </service_container/compiler_passes>` called
-``CheckTypeDeclarationsPass`` and ``CheckAliasValidityPass`` which are disabled
-by default and enabled only when executing the ``lint:container`` command.
-If you don't mind the performance loss, enable these compiler passes in
+Performing those checks whenever the container is compiled can hurt performance.
+That's why they are implemented in :doc:`compiler passes </service_container/compiler_passes>`
+called ``CheckTypeDeclarationsPass`` and ``CheckAliasValidityPass``, which are
+disabled by default and enabled only when executing the ``lint:container`` command.
+If you don't mind the performance loss, you can enable these compiler passes in
 your application.
 
+.. versionadded:: 7.1
+
+    The ``CheckAliasValidityPass`` compiler pass was introduced in Symfony 7.1.
+
 .. _container-public:
 
 Public Versus Private Services

From 323391d8876b561f1fa12d12c86c59cf75512c89 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 13 Aug 2024 10:21:05 +0200
Subject: [PATCH 318/747] [Validator] Add `Week` constraint

---
 reference/constraints/Week.rst    | 172 ++++++++++++++++++++++++++++++
 reference/constraints/map.rst.inc |   1 +
 2 files changed, 173 insertions(+)
 create mode 100644 reference/constraints/Week.rst

diff --git a/reference/constraints/Week.rst b/reference/constraints/Week.rst
new file mode 100644
index 00000000000..0aea71bee02
--- /dev/null
+++ b/reference/constraints/Week.rst
@@ -0,0 +1,172 @@
+Week
+====
+
+.. versionadded:: 7.2
+
+    The ``Week`` constraint was introduced in Symfony 7.2.
+
+Validates that a string (or an object implementing the ``Stringable`` PHP interface)
+matches a given week number. The week number format is defined by `ISO-8601`_
+and should be composed of the year and the week number, separated by a hyphen
+(e.g. ``2022-W01``).
+
+==========  =======================================================================
+Applies to  :ref:`property or method <validation-property-target>`
+Class       :class:`Symfony\\Component\\Validator\\Constraints\\Week`
+Validator   :class:`Symfony\\Component\\Validator\\Constraints\\WeekValidator`
+==========  =======================================================================
+
+Basic Usage
+-----------
+
+If you wanted to ensure that the ``startWeek`` property of an ``OnlineCourse``
+class is between the first and the twentieth week of the year 2022, you could do
+the following:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Entity/OnlineCourse.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+
+        class OnlineCourse
+        {
+            #[Assert\Week(min: '2022-W01', max: '2022-W20')]
+            protected string $startWeek;
+        }
+
+    .. code-block:: yaml
+
+        # config/validator/validation.yaml
+        App\Entity\OnlineCourse:
+            properties:
+                startWeek:
+                    - Week:
+                        min: '2022-W01'
+                        max: '2022-W20'
+
+    .. code-block:: xml
+
+        <!-- config/validator/validation.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
+
+            <class name="App\Entity\OnlineCourse">
+                <property name="startWeek">
+                    <constraint name="Week">
+                        <option name="min">2022-W01</option>
+                        <option name="max">2022-W20</option>
+                    </constraint>
+                </property>
+            </class>
+        </constraint-mapping>
+
+    .. code-block:: php
+
+        // src/Entity/OnlineCourse.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+        use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+        class OnlineCourse
+        {
+            // ...
+
+            public static function loadValidatorMetadata(ClassMetadata $metadata): void
+            {
+                $metadata->addPropertyConstraint('startWeek', new Assert\Week([
+                    'min' => '2022-W01',
+                    'max' => '2022-W20',
+                ]));
+            }
+        }
+
+.. note::
+
+    The constraint also checks that the given week exists in the calendar. For example,
+    ``2022-W53`` is not a valid week number for 2022, because 2022 only had 52 weeks.
+
+Options
+-------
+
+``min``
+~~~~~~~
+
+**type**: ``string`` **default**: ``null``
+
+The minimum week number that the value must match.
+
+``max``
+~~~~~~~
+
+**type**: ``string`` **default**: ``null``
+
+The maximum week number that the value must match.
+
+.. include:: /reference/constraints/_groups-option.rst.inc
+
+``invalidFormatMessage``
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``This value does not represent a valid week in the ISO 8601 format.``
+
+This is the message that will be shown if the value does not match the ISO 8601
+week format.
+
+``invalidWeekNumberMessage``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``The week "{{ value }}" is not a valid week.``
+
+This is the message that will be shown if the value does not match a valid week
+number.
+
+You can use the following parameters in this message:
+
+================  ==================================================
+Parameter         Description
+================  ==================================================
+``{{ value }}``   The value that was passed to the constraint
+================  ==================================================
+
+``tooLowMessage``
+~~~~~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``The value should not be before week "{{ min }}".``
+
+This is the message that will be shown if the value is lower than the minimum
+week number.
+
+You can use the following parameters in this message:
+
+================  ==================================================
+Parameter         Description
+================  ==================================================
+``{{ min }}``     The minimum week number
+================  ==================================================
+
+``tooHighMessage``
+~~~~~~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``The value should not be after week "{{ max }}".``
+
+This is the message that will be shown if the value is higher than the maximum
+week number.
+
+You can use the following parameters in this message:
+
+================  ==================================================
+Parameter         Description
+================  ==================================================
+``{{ max }}``     The maximum week number
+================  ==================================================
+
+.. include:: /reference/constraints/_payload-option.rst.inc
+
+.. _ISO-8601: https://en.wikipedia.org/wiki/ISO_8601
diff --git a/reference/constraints/map.rst.inc b/reference/constraints/map.rst.inc
index 978951c9de7..e0dbd6c4512 100644
--- a/reference/constraints/map.rst.inc
+++ b/reference/constraints/map.rst.inc
@@ -64,6 +64,7 @@ Date Constraints
 * :doc:`DateTime </reference/constraints/DateTime>`
 * :doc:`Time </reference/constraints/Time>`
 * :doc:`Timezone </reference/constraints/Timezone>`
+* :doc:`Week </reference/constraints/Week>`
 
 Choice Constraints
 ~~~~~~~~~~~~~~~~~~

From 8d5b1d357df87484858a2902baf6cd0d2e8b59dd Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 19 Aug 2024 10:48:33 +0200
Subject: [PATCH 319/747] [Uid] Add support for binary, base-32 and base-58
 representations in `Uuid::isValid()`

---
 components/uid.rst | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/components/uid.rst b/components/uid.rst
index 7195d393ed3..feb58968347 100644
--- a/components/uid.rst
+++ b/components/uid.rst
@@ -314,6 +314,30 @@ UUID objects created with the ``Uuid`` class can use the following methods
     //   * int < 0 if $uuid1 is less than $uuid4
     $uuid1->compare($uuid4); // e.g. int(4)
 
+If you're working with different UUIDs format and want to validate them,
+you can use the ``$format`` parameter of the :method:`Symfony\\Component\\Uid\\Uuid::isValid`
+method to specify the UUID format you're expecting::
+
+    use Symfony\Component\Uid\Uuid;
+
+    $isValid = Uuid::isValid('90067ce4-f083-47d2-a0f4-c47359de0f97', Uuid::FORMAT_RFC_4122); // accept only RFC 4122 UUIDs
+    $isValid = Uuid::isValid('3aJ7CNpDMfXPZrCsn4Cgey', Uuid::FORMAT_BASE_32 | Uuid::FORMAT_BASE_58); // accept multiple formats
+
+The following constants are available:
+
+* ``Uuid::FORMAT_BINARY``
+* ``Uuid::FORMAT_BASE_32``
+* ``Uuid::FORMAT_BASE_58``
+* ``Uuid::FORMAT_RFC_4122``
+
+You can also use the ``Uuid::FORMAT_ALL`` constant to accept any UUID format.
+By default, only the RFC 4122 format is accepted.
+
+.. versionadded:: 7.2
+
+    The ``$format`` parameter of the :method:`Symfony\\Component\\Uid\\Uuid::isValid`
+    method and the related constants were introduced in Symfony 7.2.
+
 Storing UUIDs in Databases
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From 3567f5b79a01bd878143a3016bc224559f5c4ec4 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 19 Aug 2024 10:58:42 +0200
Subject: [PATCH 320/747] [Serializer] Deprecate passing a non-empty CSV escape
 char

---
 components/serializer.rst | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/components/serializer.rst b/components/serializer.rst
index 09efbf44e6c..61124e3f030 100644
--- a/components/serializer.rst
+++ b/components/serializer.rst
@@ -1064,30 +1064,35 @@ which defines the configuration options for the CsvEncoder an associative array:
 
 These are the options available:
 
-======================= =====================================================  ==========================
-Option                  Description                                            Default
-======================= =====================================================  ==========================
-``csv_delimiter``       Sets the field delimiter separating values (one        ``,``
+======================= ============================================================= ==========================
+Option                  Description                                                   Default
+======================= ============================================================= ==========================
+``csv_delimiter``       Sets the field delimiter separating values (one               ``,``
                         character only)
-``csv_enclosure``       Sets the field enclosure (one character only)          ``"``
-``csv_end_of_line``     Sets the character(s) used to mark the end of each     ``\n``
+``csv_enclosure``       Sets the field enclosure (one character only)                 ``"``
+``csv_end_of_line``     Sets the character(s) used to mark the end of each            ``\n``
                         line in the CSV file
-``csv_escape_char``     Sets the escape character (at most one character)      empty string
-``csv_key_separator``   Sets the separator for array's keys during its         ``.``
+``csv_escape_char``     Deprecated. Sets the escape character (at most one character) empty string
+``csv_key_separator``   Sets the separator for array's keys during its                ``.``
                         flattening
 ``csv_headers``         Sets the order of the header and data columns
                         E.g.: if ``$data = ['c' => 3, 'a' => 1, 'b' => 2]``
                         and ``$options = ['csv_headers' => ['a', 'b', 'c']]``
                         then ``serialize($data, 'csv', $options)`` returns
-                        ``a,b,c\n1,2,3``                                       ``[]``, inferred from input data's keys
-``csv_escape_formulas`` Escapes fields containing formulas by prepending them  ``false``
+                        ``a,b,c\n1,2,3``                                              ``[]``, inferred from input data's keys
+``csv_escape_formulas`` Escapes fields containing formulas by prepending them         ``false``
                         with a ``\t`` character
-``as_collection``       Always returns results as a collection, even if only   ``true``
+``as_collection``       Always returns results as a collection, even if only          ``true``
                         one line is decoded.
-``no_headers``          Setting to ``false`` will use first row as headers.    ``false``
+``no_headers``          Setting to ``false`` will use first row as headers.           ``false``
                         ``true`` generate numeric headers.
-``output_utf8_bom``     Outputs special `UTF-8 BOM`_ along with encoded data   ``false``
-======================= =====================================================  ==========================
+``output_utf8_bom``     Outputs special `UTF-8 BOM`_ along with encoded data          ``false``
+======================= ============================================================= ==========================
+
+.. deprecated:: 7.2
+
+    The ``csv_escape_char`` option and the ``CsvEncoder::ESCAPE_CHAR_KEY``
+    constant were deprecated in Symfony 7.2.
 
 The ``XmlEncoder``
 ~~~~~~~~~~~~~~~~~~
@@ -1304,6 +1309,11 @@ you can use "context builders" to define the context using a fluent interface::
     You can also :doc:`create custom context builders </serializer/custom_context_builders>`
     to deal with your context values.
 
+.. deprecated:: 7.2
+
+    The ``CsvEncoderContextBuilder::withEscapeChar()`` method was deprecated
+    in Symfony 7.2.
+
 Skipping ``null`` Values
 ------------------------
 

From f39be7640c72c575da3320aa01ff3e7cca466660 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 19 Aug 2024 11:06:42 +0200
Subject: [PATCH 321/747] [FrameworkBundle][HttpFoundation] Deprecate
 `session.sid_length` and `session.sid_bits_per_character` config options

---
 reference/configuration/framework.rst | 8 ++++++++
 session.rst                           | 5 +++++
 2 files changed, 13 insertions(+)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 0921fe9ac2e..72c4b1b94f7 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -1874,6 +1874,10 @@ session IDs are harder to guess.
 
 If not set, ``php.ini``'s `session.sid_length`_ directive will be relied on.
 
+.. deprecated:: 7.2
+
+    The ``sid_length`` option was deprecated in Symfony 7.2.
+
 sid_bits_per_character
 ......................
 
@@ -1886,6 +1890,10 @@ most environments.
 
 If not set, ``php.ini``'s `session.sid_bits_per_character`_ directive will be relied on.
 
+.. deprecated:: 7.2
+
+    The ``sid_bits_per_character`` option was deprecated in Symfony 7.2.
+
 save_path
 .........
 
diff --git a/session.rst b/session.rst
index 29d1ba364d1..77aea3bba00 100644
--- a/session.rst
+++ b/session.rst
@@ -400,6 +400,11 @@ Check out the Symfony config reference to learn more about the other available
     ``session.auto_start = 1`` This directive should be turned off in
     ``php.ini``, in the web server directives or in ``.htaccess``.
 
+.. deprecated:: 7.2
+
+    The ``sid_length`` and ``sid_bits_per_character`` options were deprecated
+    in Symfony 7.2 and will be ignored in Symfony 8.0.
+
 The session cookie is also available in :ref:`the Response object <component-http-foundation-response>`.
 This is useful to get that cookie in the CLI context or when using PHP runners
 like Roadrunner or Swoole.

From 51fdaa869c908061f2fc355442a219c57bfc2f0a Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Tue, 20 Aug 2024 09:19:34 +0200
Subject: [PATCH 322/747] document the requests constructor argument of the
 RequestStack class

---
 components/form.rst | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/components/form.rst b/components/form.rst
index 7584d223032..f463ef5911b 100644
--- a/components/form.rst
+++ b/components/form.rst
@@ -123,8 +123,7 @@ The following snippet adds CSRF protection to the form factory::
     use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage;
 
     // creates a RequestStack object using the current request
-    $requestStack = new RequestStack();
-    $requestStack->push($request);
+    $requestStack = new RequestStack([$request]);
 
     $csrfGenerator = new UriSafeTokenGenerator();
     $csrfStorage = new SessionTokenStorage($requestStack);
@@ -135,6 +134,11 @@ The following snippet adds CSRF protection to the form factory::
         ->addExtension(new CsrfExtension($csrfManager))
         ->getFormFactory();
 
+.. versionadded:: 7.2
+
+    Support for passing requests to the constructor of the ``RequestStack``
+    class was introduced in Symfony 7.2.
+
 Internally, this extension will automatically add a hidden field to every
 form (called ``_token`` by default) whose value is automatically generated by
 the CSRF generator and validated when binding the form.

From bad2a212bf68bdfc6479765d2ecb4123677aee4e Mon Sep 17 00:00:00 2001
From: Mathieu Santostefano <msantostefano@protonmail.com>
Date: Tue, 20 Aug 2024 12:01:07 +0200
Subject: [PATCH 323/747] feat(mailer): Add Sweego Mailer doc

---
 mailer.rst  | 8 +++++++-
 webhook.rst | 3 ++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index 11acd065e52..091e6d6e5b9 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -115,6 +115,7 @@ Service               Install with                                    Webhook su
 `Resend`_             ``composer require symfony/resend-mailer``      yes
 `Scaleway`_           ``composer require symfony/scaleway-mailer``
 `SendGrid`_           ``composer require symfony/sendgrid-mailer``    yes
+`Sweego`_             ``composer require symfony/sweego-mailer``      yes
 ===================== =============================================== ===============
 
 .. versionadded:: 7.1
@@ -123,7 +124,7 @@ Service               Install with                                    Webhook su
 
 .. versionadded:: 7.2
 
-    The Mailomat and Postal integrations were introduced in Symfony 7.2.
+    The Mailomat, Postal and Sweego integrations were introduced in Symfony 7.2.
 
 .. note::
 
@@ -235,6 +236,10 @@ party provider:
 |                        | - HTTP n/a                                              |
 |                        | - API ``sendgrid+api://KEY@default``                    |
 +------------------------+---------------------------------------------------------+
+| `Sweego`_              | - SMTP ``sweego+smtp://LOGIN:PASSWORD@HOST:PORT``       |
+|                        | - HTTP n/a                                              |
+|                        | - API ``sweego+api://API_KEY@default``                  |
++------------------------+---------------------------------------------------------+
 
 .. caution::
 
@@ -2004,3 +2009,4 @@ the :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\MailerAssertionsTrait`::
 .. _`S/MIME`: https://en.wikipedia.org/wiki/S/MIME
 .. _`Scaleway`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Scaleway/README.md
 .. _`SendGrid`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Sendgrid/README.md
+.. _`Sweego`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Sweego/README.md
diff --git a/webhook.rst b/webhook.rst
index 52633ae83e5..176abc49cd2 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -31,6 +31,7 @@ Mailomat       ``mailer.webhook.request_parser.mailomat``
 Postmark       ``mailer.webhook.request_parser.postmark``
 Resend         ``mailer.webhook.request_parser.resend``
 Sendgrid       ``mailer.webhook.request_parser.sendgrid``
+Sweego         ``mailer.webhook.request_parser.sweego``
 ============== ============================================
 
 .. versionadded:: 7.1
@@ -39,7 +40,7 @@ Sendgrid       ``mailer.webhook.request_parser.sendgrid``
 
 .. versionadded:: 7.2
 
-    The ``Mailomat`` integration was introduced in Symfony 7.2.
+    The ``Mailomat`` and ``Sweego`` integrations were introduced in Symfony 7.2.
 
 .. note::
 

From 84da11cd0affbf26ba61eaaa02015f1b0c85854e Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 20 Aug 2024 14:46:44 +0200
Subject: [PATCH 324/747] [HttpFoundation] Add new parameters to
 `IpUtils::anonymize()`

---
 components/http_foundation.rst | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/components/http_foundation.rst b/components/http_foundation.rst
index 6c9210b894f..2cdd5a02702 100644
--- a/components/http_foundation.rst
+++ b/components/http_foundation.rst
@@ -362,6 +362,23 @@ analysis purposes. Use the ``anonymize()`` method from the
     $anonymousIpv6 = IpUtils::anonymize($ipv6);
     // $anonymousIpv6 = '2a01:198:603:10::'
 
+If you need even more anonymization, you can use the second and third parameters
+of the ``anonymize()`` method to specify the number of bytes that should be
+anonymized depending on the IP address format::
+
+    $ipv4 = '123.234.235.236';
+    $anonymousIpv4 = IpUtils::anonymize($ipv4, v4Bytes: 3);
+    // $anonymousIpv4 = '123.0.0.0'
+
+    $ipv6 = '2a01:198:603:10:396e:4789:8e99:890f';
+    $anonymousIpv6 = IpUtils::anonymize($ipv6, v6Bytes: 10);
+    // $anonymousIpv6 = '2a01:198:603::'
+
+.. versionadded:: 7.2
+
+    The ``v4Bytes`` and ``v6Bytes`` parameters of the ``anonymize()`` method
+    were introduced in Symfony 7.2.
+
 Check If an IP Belongs to a CIDR Subnet
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From d00645a6062158478477d9df5324d90bae3b6502 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Thu, 22 Aug 2024 09:45:19 +0200
Subject: [PATCH 325/747] [Form] Add support for the `calendar` option in
 `DateType`

---
 reference/forms/types/date.rst | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/reference/forms/types/date.rst b/reference/forms/types/date.rst
index 515c12099a1..f9c6d67a70d 100644
--- a/reference/forms/types/date.rst
+++ b/reference/forms/types/date.rst
@@ -155,6 +155,19 @@ values for the year, month and day fields::
 
 .. include:: /reference/forms/types/options/view_timezone.rst.inc
 
+``calendar``
+~~~~~~~~~~~~
+
+**type**: ``\IntlCalendar`` **default**: ``null``
+
+The calendar to use for formatting and parsing the date. The value should be
+an instance of the :phpclass:`IntlCalendar` to use. By default, the Gregorian
+calendar with the application default locale is used.
+
+.. versionadded:: 7.2
+
+    The ``calendar`` option was introduced in Symfony 7.2.
+
 .. include:: /reference/forms/types/options/date_widget.rst.inc
 
 .. include:: /reference/forms/types/options/years.rst.inc

From 429e193a40e93a3e521479aa1cc404c0b84c9df1 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Fri, 23 Aug 2024 09:30:27 +0200
Subject: [PATCH 326/747] [ExpressionLanguage] Add support for `<<`, `>>`, and
 `~` bitwise operators

---
 reference/formats/expression_language.rst | 72 +++++++++++++----------
 1 file changed, 40 insertions(+), 32 deletions(-)

diff --git a/reference/formats/expression_language.rst b/reference/formats/expression_language.rst
index e88ac7f6c24..ec592461a4f 100644
--- a/reference/formats/expression_language.rst
+++ b/reference/formats/expression_language.rst
@@ -284,6 +284,14 @@ Bitwise Operators
 * ``&`` (and)
 * ``|`` (or)
 * ``^`` (xor)
+* ``~`` (not)
+* ``<<`` (left shift)
+* ``>>`` (right shift)
+
+.. versionadded:: 7.2
+
+    Support for the ``~``, ``<<`` and ``>>`` bitwise operators was introduced
+    in Symfony 7.2.
 
 Comparison Operators
 ~~~~~~~~~~~~~~~~~~~~
@@ -449,38 +457,38 @@ parentheses in your expressions (e.g. ``(1 + 2) * 4`` or ``1 + (2 * 4)``.
 The following table summarizes the operators and their associativity from the
 **highest to the lowest precedence**:
 
-+----------------------------------------------------------+---------------+
-| Operators                                                | Associativity |
-+==========================================================+===============+
-| ``-`` , ``+`` (unary operators that add the number sign) | none          |
-+----------------------------------------------------------+---------------+
-| ``**``                                                   | right         |
-+----------------------------------------------------------+---------------+
-| ``*``, ``/``, ``%``                                      | left          |
-+----------------------------------------------------------+---------------+
-| ``not``, ``!``                                           | none          |
-+----------------------------------------------------------+---------------+
-| ``~``                                                    | left          |
-+----------------------------------------------------------+---------------+
-| ``+``, ``-``                                             | left          |
-+----------------------------------------------------------+---------------+
-| ``..``                                                   | left          |
-+----------------------------------------------------------+---------------+
-| ``==``, ``===``, ``!=``, ``!==``,                        | left          |
-| ``<``, ``>``, ``>=``, ``<=``,                            |               |
-| ``not in``, ``in``, ``contains``,                        |               |
-| ``starts with``, ``ends with``, ``matches``              |               |
-+----------------------------------------------------------+---------------+
-| ``&``                                                    | left          |
-+----------------------------------------------------------+---------------+
-| ``^``                                                    | left          |
-+----------------------------------------------------------+---------------+
-| ``|``                                                    | left          |
-+----------------------------------------------------------+---------------+
-| ``and``, ``&&``                                          | left          |
-+----------------------------------------------------------+---------------+
-| ``or``, ``||``                                           | left          |
-+----------------------------------------------------------+---------------+
++-----------------------------------------------------------------+---------------+
+| Operators                                                       | Associativity |
++=================================================================+===============+
+| ``-`` , ``+``, ``~`` (unary operators that add the number sign) | none          |
++-----------------------------------------------------------------+---------------+
+| ``**``                                                          | right         |
++-----------------------------------------------------------------+---------------+
+| ``*``, ``/``, ``%``                                             | left          |
++-----------------------------------------------------------------+---------------+
+| ``not``, ``!``                                                  | none          |
++-----------------------------------------------------------------+---------------+
+| ``~``                                                           | left          |
++-----------------------------------------------------------------+---------------+
+| ``+``, ``-``                                                    | left          |
++-----------------------------------------------------------------+---------------+
+| ``..``, ``<<``, ``>>``                                          | left          |
++-----------------------------------------------------------------+---------------+
+| ``==``, ``===``, ``!=``, ``!==``,                               | left          |
+| ``<``, ``>``, ``>=``, ``<=``,                                   |               |
+| ``not in``, ``in``, ``contains``,                               |               |
+| ``starts with``, ``ends with``, ``matches``                     |               |
++-----------------------------------------------------------------+---------------+
+| ``&``                                                           | left          |
++-----------------------------------------------------------------+---------------+
+| ``^``                                                           | left          |
++-----------------------------------------------------------------+---------------+
+| ``|``                                                           | left          |
++-----------------------------------------------------------------+---------------+
+| ``and``, ``&&``                                                 | left          |
++-----------------------------------------------------------------+---------------+
+| ``or``, ``||``                                                  | left          |
++-----------------------------------------------------------------+---------------+
 
 Built-in Objects and Variables
 ------------------------------

From d883d5659dab11da2ad39be9a380551f74682e38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20Andr=C3=A9?= <smn.andre@gmail.com>
Date: Fri, 23 Aug 2024 00:39:01 +0200
Subject: [PATCH 327/747] [Templating] [Template] Render a block with the
 `#[Template]` attribute

---
 templates.rst | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/templates.rst b/templates.rst
index 795ac3a7ac3..1af3de56c5b 100644
--- a/templates.rst
+++ b/templates.rst
@@ -632,6 +632,31 @@ This might come handy when dealing with blocks in
 :ref:`templates inheritance <template_inheritance-layouts>` or when using
 `Turbo Streams`_.
 
+Similarly, you can use the ``#[Template]`` attribute on the controller to specify a block
+to render::
+
+    // src/Controller/ProductController.php
+    namespace App\Controller;
+
+    use Symfony\Bridge\Twig\Attribute\Template;
+    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+    use Symfony\Component\HttpFoundation\Response;
+
+    class ProductController extends AbstractController
+    {
+        #[Template('product.html.twig', block: 'price_block')]
+        public function price(): array
+        {
+            return [
+                // ...
+            ];
+        }
+    }
+
+.. versionadded:: 7.2
+
+    The ``#[Template]`` attribute's ``block`` argument was introduced in Symfony 7.2.
+
 Rendering a Template in Services
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From d158b5544cb173ea520724e56df2a1ba1c8c84c0 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 26 Aug 2024 09:19:25 +0200
Subject: [PATCH 328/747] Minor tweak

---
 templates.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/templates.rst b/templates.rst
index 1af3de56c5b..2379a3568dc 100644
--- a/templates.rst
+++ b/templates.rst
@@ -632,8 +632,8 @@ This might come handy when dealing with blocks in
 :ref:`templates inheritance <template_inheritance-layouts>` or when using
 `Turbo Streams`_.
 
-Similarly, you can use the ``#[Template]`` attribute on the controller to specify a block
-to render::
+Similarly, you can use the ``#[Template]`` attribute on the controller to specify
+a block to render::
 
     // src/Controller/ProductController.php
     namespace App\Controller;

From bec9e5faa881623aa75a03a78212315f44799a43 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Thu, 22 Aug 2024 14:16:06 +0200
Subject: [PATCH 329/747] [Validator] Add `CompoundConstraintTestCase` to ease
 testing Compound Constraints

---
 validation/custom_constraint.rst | 74 ++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/validation/custom_constraint.rst b/validation/custom_constraint.rst
index 9f0ca4ca07b..4504ceb4012 100644
--- a/validation/custom_constraint.rst
+++ b/validation/custom_constraint.rst
@@ -502,6 +502,9 @@ A class constraint validator must be applied to the class itself:
 Testing Custom Constraints
 --------------------------
 
+Atomic Constraints
+~~~~~~~~~~~~~~~~~~
+
 Use the :class:`Symfony\\Component\\Validator\\Test\\ConstraintValidatorTestCase`
 class to simplify writing unit tests for your custom constraints::
 
@@ -545,3 +548,74 @@ class to simplify writing unit tests for your custom constraints::
             // ...
         }
     }
+
+Compound Constraints
+~~~~~~~~~~~~~~~~~~~~
+
+Let's say you create a compound constraint that checks if a string meets
+your minimum requirements for your password policy::
+
+    // src/Validator/PasswordRequirements.php
+    namespace App\Validator;
+
+    use Symfony\Component\Validator\Constraints as Assert;
+
+    #[\Attribute]
+    class PasswordRequirements extends Assert\Compound
+    {
+        protected function getConstraints(array $options): array
+        {
+            return [
+                new Assert\NotBlank(allowNull: false),
+                new Assert\Length(min: 8, max: 255),
+                new Assert\NotCompromisedPassword(),
+                new Assert\Type('string'),
+                new Assert\Regex('/[A-Z]+/'),
+            ];
+        }
+    }
+
+You can use the :class:`Symfony\\Component\\Validator\\Test\\CompoundConstraintTestCase`
+class to check precisely which of the constraints failed to pass::
+
+    // tests/Validator/PasswordRequirementsTest.php
+    namespace App\Tests\Validator;
+
+    use App\Validator\PasswordRequirements;
+    use Symfony\Component\Validator\Constraints as Assert;
+    use Symfony\Component\Validator\Test\CompoundConstraintTestCase;
+
+    /**
+     * @extends CompoundConstraintTestCase<PasswordRequirements>
+     */
+    class PasswordRequirementsTest extends CompoundConstraintTestCase
+    {
+        public function createCompound(): Assert\Compound
+        {
+            return new PasswordRequirements();
+        }
+
+        public function testInvalidPassword(): void
+        {
+            $this->validateValue('azerty123');
+
+            // check all constraints pass except for the
+            // password leak and the uppercase letter checks
+            $this->assertViolationsRaisedByCompound([
+                new Assert\NotCompromisedPassword(),
+                new Assert\Regex('/[A-Z]+/'),
+            ]);
+        }
+
+        public function testValid(): void
+        {
+            $this->validateValue('VERYSTR0NGP4$$WORD#%!');
+
+            $this->assertNoViolation();
+        }
+    }
+
+.. versionadded:: 7.2
+
+    The :class:`Symfony\\Component\\Validator\\Test\\CompoundConstraintTestCase`
+    class was introduced in Symfony 7.2.

From 3f0fdbad1f95f056c576e2d34f1576c4fe27c720 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 26 Aug 2024 10:21:56 +0200
Subject: [PATCH 330/747] Tweaks

---
 reference/constraints/Week.rst | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/reference/constraints/Week.rst b/reference/constraints/Week.rst
index 0aea71bee02..26d82777636 100644
--- a/reference/constraints/Week.rst
+++ b/reference/constraints/Week.rst
@@ -5,10 +5,9 @@ Week
 
     The ``Week`` constraint was introduced in Symfony 7.2.
 
-Validates that a string (or an object implementing the ``Stringable`` PHP interface)
-matches a given week number. The week number format is defined by `ISO-8601`_
-and should be composed of the year and the week number, separated by a hyphen
-(e.g. ``2022-W01``).
+Validates that a given string (or an object implementing the ``Stringable`` PHP
+interface) represents a valid week number according to the `ISO-8601`_ standard
+(e.g. ``2025-W01``).
 
 ==========  =======================================================================
 Applies to  :ref:`property or method <validation-property-target>`
@@ -87,10 +86,11 @@ the following:
             }
         }
 
-.. note::
-
-    The constraint also checks that the given week exists in the calendar. For example,
-    ``2022-W53`` is not a valid week number for 2022, because 2022 only had 52 weeks.
+This constraint not only checks that the value matches the week number pattern,
+but it also verifies that the specified week actually exists in the calendar.
+According to the ISO-8601 standard, years can have either 52 or 53 weeks. For example,
+``2022-W53`` is not a valid because 2022 only had 52 weeks; but ``2020-W53`` is
+valid because 2020 had 53 weeks.
 
 Options
 -------
@@ -169,4 +169,4 @@ Parameter         Description
 
 .. include:: /reference/constraints/_payload-option.rst.inc
 
-.. _ISO-8601: https://en.wikipedia.org/wiki/ISO_8601
+.. _`ISO-8601`: https://en.wikipedia.org/wiki/ISO_8601

From 34d159469bd81267e3ae9cfe8d2b65993fd148f1 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 26 Aug 2024 10:57:07 +0200
Subject: [PATCH 331/747] Minor tweak

---
 validation/custom_constraint.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/validation/custom_constraint.rst b/validation/custom_constraint.rst
index 4504ceb4012..435b976d1d3 100644
--- a/validation/custom_constraint.rst
+++ b/validation/custom_constraint.rst
@@ -552,8 +552,8 @@ class to simplify writing unit tests for your custom constraints::
 Compound Constraints
 ~~~~~~~~~~~~~~~~~~~~
 
-Let's say you create a compound constraint that checks if a string meets
-your minimum requirements for your password policy::
+Consider the following compound constraint that checks if a string meets
+the minimum requirements for your password policy::
 
     // src/Validator/PasswordRequirements.php
     namespace App\Validator;

From 41f17860c70df6743740b8c5a0aff21606cee7ac Mon Sep 17 00:00:00 2001
From: eltharin <eltharin18@hotmail.fr>
Date: Thu, 15 Aug 2024 15:21:16 +0200
Subject: [PATCH 332/747] [Scheduler] Add capability to skip missed periodic
 tasks, only the last schedule will be called

---
 scheduler.rst | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/scheduler.rst b/scheduler.rst
index c890b1a1aec..be4f2ca138d 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -889,6 +889,27 @@ This allows the system to retain the state of the schedule, ensuring that when a
         }
     }
 
+With ``stateful`` option, All missed messages will be handled, If you nedd handle your message only once you can use the ``processOnlyLastMissedRun`` option.::
+
+    // src/Scheduler/SaleTaskProvider.php
+    namespace App\Scheduler;
+
+    #[AsSchedule('uptoyou')]
+    class SaleTaskProvider implements ScheduleProviderInterface
+    {
+        public function getSchedule(): Schedule
+        {
+            $this->removeOldReports = RecurringMessage::cron('3 8 * * 1', new CleanUpOldSalesReport());
+
+            return $this->schedule ??= (new Schedule())
+                ->with(
+                    // ...
+                )
+                ->stateful($this->cache)
+                ->processOnlyLastMissedRun(true)
+        }
+    }
+
 To scale your schedules more effectively, you can use multiple workers. In such
 cases, a good practice is to add a :doc:`lock </components/lock>` to prevent the
 same task more than once::

From 0f91311c8572b58c69097b901c7d76cf03ac993a Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 26 Aug 2024 12:50:13 +0200
Subject: [PATCH 333/747] Minor tweaks

---
 scheduler.rst | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/scheduler.rst b/scheduler.rst
index be4f2ca138d..081f4efd498 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -869,7 +869,8 @@ While this behavior may not necessarily pose a problem, there is a possibility t
 
 That's why the scheduler allows to remember the last execution date of a message
 via the ``stateful`` option (and the :doc:`Cache component </components/cache>`).
-This allows the system to retain the state of the schedule, ensuring that when a worker is restarted, it resumes from the point it left off.::
+This allows the system to retain the state of the schedule, ensuring that when a
+worker is restarted, it resumes from the point it left off::
 
     // src/Scheduler/SaleTaskProvider.php
     namespace App\Scheduler;
@@ -889,7 +890,8 @@ This allows the system to retain the state of the schedule, ensuring that when a
         }
     }
 
-With ``stateful`` option, All missed messages will be handled, If you nedd handle your message only once you can use the ``processOnlyLastMissedRun`` option.::
+With the ``stateful`` option, all missed messages will be handled. If you need to
+handle a message only once, you can use the ``processOnlyLastMissedRun`` option::
 
     // src/Scheduler/SaleTaskProvider.php
     namespace App\Scheduler;
@@ -910,6 +912,10 @@ With ``stateful`` option, All missed messages will be handled, If you nedd handl
         }
     }
 
+.. versionadded:: 7.2
+
+    The ``processOnlyLastMissedRun`` option was introduced in Symfony 7.2.
+
 To scale your schedules more effectively, you can use multiple workers. In such
 cases, a good practice is to add a :doc:`lock </components/lock>` to prevent the
 same task more than once::

From 23838fd198c9a98731567284306d56b6c78f7e32 Mon Sep 17 00:00:00 2001
From: Thibaut THOUEMENT <thouement.t@outlook.fr>
Date: Fri, 23 Aug 2024 22:10:10 +0200
Subject: [PATCH 334/747] [Validator] Add errorPath to Unique constraint

---
 reference/constraints/Unique.rst | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/reference/constraints/Unique.rst b/reference/constraints/Unique.rst
index 8954f455086..7c4f78cfcc3 100644
--- a/reference/constraints/Unique.rst
+++ b/reference/constraints/Unique.rst
@@ -170,6 +170,15 @@ collection::
 
 .. include:: /reference/constraints/_groups-option.rst.inc
 
+``errorPath``
+~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``null``
+
+This option allows you to define a custom path for your message.
+``#[Assert\Unique(fields: ['latitude', 'longitude'], errorPath: 'point_of_interest')]``
+Instead of ``0: "Error message"``, it will be : ``0.point_of_interest: "Error message"``
+
 ``message``
 ~~~~~~~~~~~
 

From 03713d55356555cf5933daa8bc1cbe821ccf1591 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 26 Aug 2024 16:58:22 +0200
Subject: [PATCH 335/747] Reword

---
 reference/constraints/Unique.rst | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/reference/constraints/Unique.rst b/reference/constraints/Unique.rst
index 7c4f78cfcc3..68754738271 100644
--- a/reference/constraints/Unique.rst
+++ b/reference/constraints/Unique.rst
@@ -175,9 +175,16 @@ collection::
 
 **type**: ``string`` **default**: ``null``
 
-This option allows you to define a custom path for your message.
-``#[Assert\Unique(fields: ['latitude', 'longitude'], errorPath: 'point_of_interest')]``
-Instead of ``0: "Error message"``, it will be : ``0.point_of_interest: "Error message"``
+.. versionadded:: 7.2
+
+    The ``errorPath`` option was introduced in Symfony 7.2.
+
+If a validation error occurs, the error message is, by default, bound to the
+first element in the collection. Use this option to bind the error message to a
+specific field within the first item of the collection.
+
+The value of this option must use any :doc:`valid PropertyAccess syntax </components/property_access>`
+(e.g. ``'point_of_interest'``, ``'user.email'``).
 
 ``message``
 ~~~~~~~~~~~

From 45ba59fd12b5db3fa49a6cb6ac38683d9119442b Mon Sep 17 00:00:00 2001
From: Ahmed Ghanem <124502255+ahmedghanem00@users.noreply.github.com>
Date: Mon, 29 Jul 2024 02:56:36 +0300
Subject: [PATCH 336/747] [Notifier] Create `DesktopChannel` and `JoliNotif`
 bridge

---
 notifier.rst | 84 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 80 insertions(+), 4 deletions(-)

diff --git a/notifier.rst b/notifier.rst
index 6d506910ead..4df4590235e 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -16,8 +16,8 @@ Get the Notifier installed using:
 
 .. _channels-chatters-texters-email-and-browser:
 
-Channels: Chatters, Texters, Email, Browser and Push
-----------------------------------------------------
+Channels: Chatters, Texters, Email, Browser, Push and Desktop
+-------------------------------------------------------------
 
 The notifier component can send notifications to different channels. Each
 channel can integrate with different providers (e.g. Slack or Twilio SMS)
@@ -32,6 +32,7 @@ The notifier component supports the following channels:
 * :ref:`Email channel <notifier-email-channel>` integrates the :doc:`Symfony Mailer </mailer>`;
 * Browser channel uses :ref:`flash messages <flash-messages>`.
 * :ref:`Push channel <notifier-push-channel>` sends notifications to phones and browsers via push notifications.
+* :ref:`Desktop channel <notifier-desktop-channel>` displays desktop notifications on the same host machine.
 
 .. tip::
 
@@ -623,6 +624,79 @@ configure the ``texter_transports``:
             ;
         };
 
+.. _notifier-desktop-channel:
+
+Desktop Channel
+~~~~~~~~~~~~~~~
+
+The desktop channel is used to display desktop notifications on the same host machine using
+:class:`Symfony\\Component\\Notifier\\Texter` classes. Currently, Symfony
+is integrated with the following providers:
+
+===============  ====================================  ==============================================================================
+Provider         Package                               DSN
+===============  ====================================  ==============================================================================
+`JoliNotif`_     ``symfony/joli-notif-notifier``       ``jolinotif://default``
+===============  ====================================  ==============================================================================
+
+.. versionadded: 7.2
+
+    The JoliNotif bridge was introduced in Symfony 7.2.
+
+To enable a texter, add the correct DSN in your ``.env`` file and
+configure the ``texter_transports``:
+
+.. code-block:: bash
+
+    # .env
+    JOLINOTIF=jolinotif://default
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/notifier.yaml
+        framework:
+            notifier:
+                texter_transports:
+                    jolinotif: '%env(JOLINOTIF)%'
+
+    .. code-block:: xml
+
+        <!-- config/packages/notifier.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony
+                https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <framework:config>
+                <framework:notifier>
+                    <framework:texter-transport name="jolinotif">
+                        %env(JOLINOTIF)%
+                    </framework:texter-transport>
+                </framework:notifier>
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/notifier.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            $framework->notifier()
+                ->texterTransport('jolinotif', env('JOLINOTIF'))
+            ;
+        };
+
+.. versionadded:: 7.2
+
+    The ``Desktop`` channel was introduced in Symfony 7.2.
+
 Configure to use Failover or Round-Robin Transports
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -926,9 +1000,10 @@ and its ``asChatMessage()`` method::
 
 The
 :class:`Symfony\\Component\\Notifier\\Notification\\SmsNotificationInterface`,
-:class:`Symfony\\Component\\Notifier\\Notification\\EmailNotificationInterface`
-and
+:class:`Symfony\\Component\\Notifier\\Notification\\EmailNotificationInterface`,
 :class:`Symfony\\Component\\Notifier\\Notification\\PushNotificationInterface`
+and
+:class:`Symfony\\Component\\Notifier\\Notification\\DesktopNotificationInterface`
 also exists to modify messages sent to those channels.
 
 Customize Browser Notifications (Flash Messages)
@@ -1114,6 +1189,7 @@ is dispatched. Listeners receive a
 .. _`Infobip`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Infobip/README.md
 .. _`Iqsms`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Iqsms/README.md
 .. _`iSendPro`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Isendpro/README.md
+.. _`JoliNotif`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/JoliNotif/README.md
 .. _`KazInfoTeh`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/KazInfoTeh/README.md
 .. _`LINE Notify`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/LineNotify/README.md
 .. _`LightSms`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/LightSms/README.md

From cc4de4e630189e65ca2e74f98b469d18d20aca28 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 28 Aug 2024 13:13:14 +0200
Subject: [PATCH 337/747] Keep a reference to not break existing links

---
 notifier.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/notifier.rst b/notifier.rst
index 4df4590235e..5f38a078f4c 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -15,6 +15,7 @@ Get the Notifier installed using:
     $ composer require symfony/notifier
 
 .. _channels-chatters-texters-email-and-browser:
+.. _channels-chatters-texters-email-browser-and-push:
 
 Channels: Chatters, Texters, Email, Browser, Push and Desktop
 -------------------------------------------------------------

From 63c749ff15aa15d93539695e7abdb5d3a2e21b73 Mon Sep 17 00:00:00 2001
From: Antoine M <amakdessi@me.com>
Date: Thu, 29 Aug 2024 13:50:09 +0200
Subject: [PATCH 338/747] chore: relocate the sqlite note block in a better
 place

---
 doctrine.rst | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/doctrine.rst b/doctrine.rst
index 770a7b32a0a..f3a34757374 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -174,13 +174,6 @@ Whoa! You now have a new ``src/Entity/Product.php`` file::
     Confused why the price is an integer? Don't worry: this is just an example.
     But, storing prices as integers (e.g. 100 = $1 USD) can avoid rounding issues.
 
-.. note::
-
-    If you are using an SQLite database, you'll see the following error:
-    *PDOException: SQLSTATE[HY000]: General error: 1 Cannot add a NOT NULL
-    column with default value NULL*. Add a ``nullable=true`` option to the
-    ``description`` property to fix the problem.
-
 .. caution::
 
     There is a `limit of 767 bytes for the index key prefix`_ when using
@@ -323,6 +316,13 @@ The migration system is *smart*. It compares all of your entities with the curre
 state of the database and generates the SQL needed to synchronize them! Like
 before, execute your migrations:
 
+.. note::
+
+    If you are using an SQLite database, you'll see the following error:
+    *PDOException: SQLSTATE[HY000]: General error: 1 Cannot add a NOT NULL
+    column with default value NULL*. Add a ``nullable=true`` option to the
+    ``description`` property to fix the problem.
+
 .. code-block:: terminal
 
     $ php bin/console doctrine:migrations:migrate

From ce6e820aa394a0e6f048e4d8c647de34cc8da85a Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 30 Aug 2024 08:26:57 +0200
Subject: [PATCH 339/747] Minor tweak

---
 doctrine.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/doctrine.rst b/doctrine.rst
index f3a34757374..aba27545211 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -316,17 +316,17 @@ The migration system is *smart*. It compares all of your entities with the curre
 state of the database and generates the SQL needed to synchronize them! Like
 before, execute your migrations:
 
-.. note::
+.. code-block:: terminal
+
+    $ php bin/console doctrine:migrations:migrate
+
+.. caution::
 
     If you are using an SQLite database, you'll see the following error:
     *PDOException: SQLSTATE[HY000]: General error: 1 Cannot add a NOT NULL
     column with default value NULL*. Add a ``nullable=true`` option to the
     ``description`` property to fix the problem.
 
-.. code-block:: terminal
-
-    $ php bin/console doctrine:migrations:migrate
-
 This will only execute the *one* new migration file, because DoctrineMigrationsBundle
 knows that the first migration was already executed earlier. Behind the scenes, it
 manages a ``migration_versions`` table to track this.

From bc88843304a3f7d512aec8cd168e0630abec687c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Maxime=20H=C3=A9lias?= <maximehelias16@gmail.com>
Date: Wed, 28 Aug 2024 21:45:50 +0200
Subject: [PATCH 340/747] [FrameworkBundle][HttpClient] Adding an explanation
 of ThrottlingHttpClient integration with the Framework

---
 http_client.rst | 104 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 89 insertions(+), 15 deletions(-)

diff --git a/http_client.rst b/http_client.rst
index f1c150b54eb..91b91ebc4a5 100644
--- a/http_client.rst
+++ b/http_client.rst
@@ -1488,30 +1488,104 @@ Limit the Number of Requests
 ----------------------------
 
 This component provides a :class:`Symfony\\Component\\HttpClient\\ThrottlingHttpClient`
-decorator that allows to limit the number of requests within a certain period.
+decorator that allows to limit the number of requests within a certain period,
+potentially delaying calls based on the rate limiting policy.
 
 The implementation leverages the
 :class:`Symfony\\Component\\RateLimiter\\LimiterInterface` class under the hood
 so the :doc:`Rate Limiter component </rate_limiter>` needs to be
 installed in your application::
 
-    use Symfony\Component\HttpClient\HttpClient;
-    use Symfony\Component\HttpClient\ThrottlingHttpClient;
-    use Symfony\Component\RateLimiter\LimiterInterface;
+.. configuration-block::
 
-    $rateLimiter = ...; // $rateLimiter is an instance of Symfony\Component\RateLimiter\LimiterInterface
-    $client = HttpClient::create();
-    $client = new ThrottlingHttpClient($client, $rateLimiter);
+    .. code-block:: yaml
 
-    $requests = [];
-    for ($i = 0; $i < 100; $i++) {
-        $requests[] = $client->request('GET', 'https://example.com');
-    }
+        # config/packages/framework.yaml
+        framework:
+            http_client:
+                scoped_clients:
+                    example.client:
+                        base_uri: 'https://example.com'
+                        rate_limiter: 'http_example_limiter'
 
-    foreach ($requests as $request) {
-        // Depending on rate limiting policy, calls will be delayed
-        $output->writeln($request->getContent());
-    }
+            rate_limiter:
+                # Don't send more than 10 requests in 5 seconds
+                http_example_limiter:
+                    policy: 'token_bucket'
+                    limit: 10
+                    rate: { interval: '5 seconds', amount: 10 }
+
+    .. code-block:: xml
+
+        <!-- config/packages/framework.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <framework:config>
+                <framework:http-client>
+                    <framework:scoped-client name="example.client"
+                        base-uri="https://example.com"
+                        rate-limiter="http_example_limiter"
+                    />
+                </framework:http-client>
+
+                <framework:rate-limiter>
+                    <!-- Don't send more than 10 requests in 5 seconds -->
+                    <framework:limiter name="http_example_limiter"
+                        policy="token_bucket"
+                        limit="10"
+                    >
+                        <framework:rate interval="5 seconds" amount="10"/>
+                    </framework:limiter>
+                </framework:rate-limiter>
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/framework.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            $framework->httpClient()->scopedClient('example.client')
+                ->baseUri('https://example.com')
+                ->rateLimiter('http_example_limiter');
+                // ...
+            ;
+
+            $framework->rateLimiter()
+                // Don't send more than 10 requests in 5 seconds
+                ->limiter('http_example_limiter')
+                    ->policy('token_bucket')
+                    ->limit(10)
+                    ->rate()
+                        ->interval('5 seconds')
+                        ->amount(10)
+                ;
+        };
+
+    .. code-block:: php-standalone
+
+        use Symfony\Component\HttpClient\HttpClient;
+        use Symfony\Component\HttpClient\ThrottlingHttpClient;
+        use Symfony\Component\RateLimiter\RateLimiterFactory;
+        use Symfony\Component\RateLimiter\Storage\InMemoryStorage;
+
+        $factory = new RateLimiterFactory([
+            'id' => 'http_example_limiter',
+            'policy' => 'token_bucket',
+            'limit' => 10,
+            'rate' => ['interval' => '5 seconds', 'amount' => 10],
+        ], new InMemoryStorage());
+        $limiter = $factory->create();
+
+        $client = HttpClient::createForBaseUri('https://example.com');
+        $throttlingClient = new ThrottlingHttpClient($client, $limiter);
 
 .. versionadded:: 7.1
 

From 0c1a63900ab6ac2aa0f3848541f11ef47b932232 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Mon, 2 Sep 2024 13:55:32 +0200
Subject: [PATCH 341/747] fix typo

---
 reference/constraints/Week.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/constraints/Week.rst b/reference/constraints/Week.rst
index 26d82777636..f107d8b4192 100644
--- a/reference/constraints/Week.rst
+++ b/reference/constraints/Week.rst
@@ -89,7 +89,7 @@ the following:
 This constraint not only checks that the value matches the week number pattern,
 but it also verifies that the specified week actually exists in the calendar.
 According to the ISO-8601 standard, years can have either 52 or 53 weeks. For example,
-``2022-W53`` is not a valid because 2022 only had 52 weeks; but ``2020-W53`` is
+``2022-W53`` is not valid because 2022 only had 52 weeks; but ``2020-W53`` is
 valid because 2020 had 53 weeks.
 
 Options

From dea8bf6a3a928bd4f6eceedc69e60a70b0668633 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Tue, 3 Sep 2024 09:50:17 +0200
Subject: [PATCH 342/747] Translation - fix lint for ci

---
 translation.rst | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/translation.rst b/translation.rst
index 50de01cfc1e..f1704ddccb2 100644
--- a/translation.rst
+++ b/translation.rst
@@ -467,10 +467,6 @@ The ``translation:extract`` command looks for missing translations in:
 
         $ composer require nikic/php-parser
 
-    .. versionadded:: 6.2
-
-        The AST parser support was introduced in Symfony 6.2.
-
 .. _translation-resource-locations:
 
 Translation Resource/File Names and Locations

From d3e3ab7c04f6b95bf693a5a6026ed972c530e0b9 Mon Sep 17 00:00:00 2001
From: Javier Spagnoletti <phansys@gmail.com>
Date: Fri, 6 Sep 2024 13:24:28 -0300
Subject: [PATCH 343/747] [Messenger] Add missing backticks for inline snippets

---
 messenger.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index b2ede04da43..35e82591357 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1679,7 +1679,7 @@ redis_sentinel           support is disabled
 
 .. versionadded:: 7.1
 
-    The option `redis_sentinel` as an alias for `sentinel_master` was introduced
+    The option ``redis_sentinel`` as an alias for ``sentinel_master`` was introduced
     in Symfony 7.1.
 
 .. caution::

From 31a33bf2d9e5929f834d25cfad93ac21852bf9ad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rapha=C3=ABl=20Geffroy?=
 <81738559+raphael-geffroy@users.noreply.github.com>
Date: Fri, 6 Sep 2024 17:53:21 +0200
Subject: [PATCH 344/747] [FrameworkBundle] Remove default value for
 `gc_probability` config option

---
 reference/configuration/framework.rst | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 1e9e43faa0f..c3f341f578b 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -1845,13 +1845,19 @@ If not set, ``php.ini``'s `session.gc_divisor`_ directive will be relied on.
 gc_probability
 ..............
 
-**type**: ``integer`` **default**: ``1``
+**type**: ``integer``
 
 This defines the probability that the garbage collector (GC) process is
 started on every session initialization. The probability is calculated by
 using ``gc_probability`` / ``gc_divisor``, e.g. 1/100 means there is a 1%
 chance that the GC process will start on each request.
 
+If not set, ``php.ini``'s `session.gc_probability`_ directive will be relied on.
+
+.. versionadded:: 7.2
+
+    Relying on ``php.ini``'s directive as default for ``gc_probability`` was introduced in symfony 7.2.
+
 gc_maxlifetime
 ..............
 
@@ -3893,6 +3899,7 @@ The attributes can also be added to interfaces directly::
 .. _`session.cookie_samesite`: https://www.php.net/manual/en/session.configuration.php#ini.session.cookie-samesite
 .. _`session.cookie_secure`: https://www.php.net/manual/en/session.configuration.php#ini.session.cookie-secure
 .. _`session.gc_divisor`: https://www.php.net/manual/en/session.configuration.php#ini.session.gc-divisor
+.. _`session.gc_probability`: https://www.php.net/manual/en/session.configuration.php#ini.session.gc-probability
 .. _`session.gc_maxlifetime`: https://www.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime
 .. _`session.sid_length`: https://www.php.net/manual/en/session.configuration.php#ini.session.sid-length
 .. _`session.sid_bits_per_character`: https://www.php.net/manual/en/session.configuration.php#ini.session.sid-bits-per-character

From 5c72f37bca564690a8af6f9797f3eed7e91d0cd8 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 9 Sep 2024 08:42:30 +0200
Subject: [PATCH 345/747] Minor tweak

---
 reference/configuration/framework.rst | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index c3f341f578b..bdcbc4a55af 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -1852,11 +1852,13 @@ started on every session initialization. The probability is calculated by
 using ``gc_probability`` / ``gc_divisor``, e.g. 1/100 means there is a 1%
 chance that the GC process will start on each request.
 
-If not set, ``php.ini``'s `session.gc_probability`_ directive will be relied on.
+If not set, Symfony will use the value of the `session.gc_probability`_ directive
+in the ``php.ini`` configuration file.
 
 .. versionadded:: 7.2
 
-    Relying on ``php.ini``'s directive as default for ``gc_probability`` was introduced in symfony 7.2.
+    Relying on ``php.ini``'s directive as default for ``gc_probability`` was
+    introduced in Symfony 7.2.
 
 gc_maxlifetime
 ..............

From e425caf94ceb2d7336a5aff5e7832529d6ce8ebd Mon Sep 17 00:00:00 2001
From: Kevin Bond <kevinbond@gmail.com>
Date: Thu, 12 Sep 2024 22:39:59 -0400
Subject: [PATCH 346/747] [Mailer] add Mailtrap docs

---
 mailer.rst | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/mailer.rst b/mailer.rst
index 21032732c4b..a8d0eda3072 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -109,6 +109,7 @@ Service               Install with                                    Webhook su
 `Mailomat`_           ``composer require symfony/mailomat-mailer``    yes
 `MailPace`_           ``composer require symfony/mail-pace-mailer``
 `MailerSend`_         ``composer require symfony/mailer-send-mailer``
+`Mailtrap`_           ``composer require symfony/mailtrap-mailer``
 `Mandrill`_           ``composer require symfony/mailchimp-mailer``
 `Postal`_             ``composer require symfony/postal-mailer``
 `Postmark`_           ``composer require symfony/postmark-mailer``    yes
@@ -124,7 +125,7 @@ Service               Install with                                    Webhook su
 
 .. versionadded:: 7.2
 
-    The Mailomat, Postal and Sweego integrations were introduced in Symfony 7.2.
+    The Mailomat, Mailtrap, Postal and Sweego integrations were introduced in Symfony 7.2.
 
 .. note::
 
@@ -216,6 +217,10 @@ party provider:
 |                        | - HTTP n/a                                              |
 |                        | - API ``mailpace+api://API_TOKEN@default``              |
 +------------------------+---------------------------------------------------------+
+| `Mailtrap`_            | - SMTP ``mailtrap+smtp://PASSWORD@default``             |
+|                        | - HTTP n/a                                              |
+|                        | - API ``mailtrap+api://API_TOKEN@default``              |
++------------------------+---------------------------------------------------------+
 | `Postal`_              | - SMTP n/a                                              |
 |                        | - HTTP n/a                                              |
 |                        | - API ``postal+api://API_KEY@BASE_URL``                 |
@@ -1581,6 +1586,7 @@ The following transports currently support tags and metadata:
 
 * Brevo
 * Mailgun
+* Mailtrap
 * Mandrill
 * Postmark
 * Sendgrid
@@ -2000,6 +2006,7 @@ the :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\MailerAssertionsTrait`::
 .. _`PEM encoded`: https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail
 .. _`Postal`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Postal/README.md
 .. _`Postmark`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Postmark/README.md
+.. _`Mailtrap`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Mailtrap/README.md
 .. _`Resend`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Resend/README.md
 .. _`RFC 3986`: https://www.ietf.org/rfc/rfc3986.txt
 .. _`S/MIME`: https://en.wikipedia.org/wiki/S/MIME

From 4dc4e9d75724eb3874149e7a5455f81dce17cdef Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 17 Sep 2024 10:53:05 +0200
Subject: [PATCH 347/747] Minor tweak

---
 reference/configuration/framework.rst | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 80c1944eea1..19f72bb6cb3 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -1884,7 +1884,8 @@ If not set, ``php.ini``'s `session.sid_length`_ directive will be relied on.
 
 .. deprecated:: 7.2
 
-    The ``sid_length`` option was deprecated in Symfony 7.2.
+    The ``sid_length`` option was deprecated in Symfony 7.2. No alternative is
+    provided as PHP 8.4 has deprecated the related option.
 
 sid_bits_per_character
 ......................
@@ -1900,7 +1901,8 @@ If not set, ``php.ini``'s `session.sid_bits_per_character`_ directive will be re
 
 .. deprecated:: 7.2
 
-    The ``sid_bits_per_character`` option was deprecated in Symfony 7.2.
+    The ``sid_bits_per_character`` option was deprecated in Symfony 7.2. No alternative
+    is provided as PHP 8.4 has deprecated the related option.
 
 save_path
 .........

From 36a7c6dd137a8e819360be1b7e107732b0cdd04b Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 17 Sep 2024 14:31:19 +0200
Subject: [PATCH 348/747] [Uid] Add the `Uuid::FORMAT_RFC_9562` constant

---
 components/uid.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/components/uid.rst b/components/uid.rst
index feb58968347..73974ef8732 100644
--- a/components/uid.rst
+++ b/components/uid.rst
@@ -329,6 +329,7 @@ The following constants are available:
 * ``Uuid::FORMAT_BASE_32``
 * ``Uuid::FORMAT_BASE_58``
 * ``Uuid::FORMAT_RFC_4122``
+* ``Uuid::FORMAT_RFC_9562`` (equivalent to ``Uuid::FORMAT_RFC_4122``)
 
 You can also use the ``Uuid::FORMAT_ALL`` constant to accept any UUID format.
 By default, only the RFC 4122 format is accepted.

From 7a8d0c44f97540e3ef80df087828174f5c8ebec9 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 19 Sep 2024 09:12:56 +0200
Subject: [PATCH 349/747] [Translation] Mention the support of segment
 attributes in XLIFF

---
 reference/formats/xliff.rst | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/reference/formats/xliff.rst b/reference/formats/xliff.rst
index acb9af36014..b5dc99b4186 100644
--- a/reference/formats/xliff.rst
+++ b/reference/formats/xliff.rst
@@ -29,7 +29,7 @@ loaded/dumped inside a Symfony application:
                     <note category="approved">true</note>
                     <note category="section" priority="1">user login</note>
                 </notes>
-                <segment>
+                <segment state="translated" subState="Some custom value">
                     <source>original-content</source>
                     <target>translated-content</target>
                 </segment>
@@ -37,4 +37,8 @@ loaded/dumped inside a Symfony application:
         </file>
     </xliff>
 
+.. versionadded:: 7.2
+
+    The support of attributes in the ``<segment>`` element was introduced in Symfony 7.2.
+
 .. _XLIFF: https://docs.oasis-open.org/xliff/xliff-core/v2.1/xliff-core-v2.1.html

From d971cea1c706ff93df2c16bedfd7c0223a5514a8 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 19 Sep 2024 13:30:17 +0200
Subject: [PATCH 350/747] =?UTF-8?q?[HttpFoundation]=C2=A0Document=20the=20?=
 =?UTF-8?q?PRIVATE=5FSUBNETS=20string?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 deployment/proxies.rst | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/deployment/proxies.rst b/deployment/proxies.rst
index 40c2550ee2c..fc6f855451d 100644
--- a/deployment/proxies.rst
+++ b/deployment/proxies.rst
@@ -143,9 +143,17 @@ In this case, you'll need to - *very carefully* - trust *all* proxies.
        framework:
            # ...
            # trust *all* requests (the 'REMOTE_ADDR' string is replaced at
-           # run time by $_SERVER['REMOTE_ADDR'])
+           # runtime by $_SERVER['REMOTE_ADDR'])
            trusted_proxies: '127.0.0.1,REMOTE_ADDR'
 
+           # you can also use the 'PRIVATE_SUBNETS' string, which is replaced at
+           # runtime by the IpUtils::PRIVATE_SUBNETS constant
+           # trusted_proxies: '127.0.0.1,PRIVATE_SUBNETS'
+
+.. versionadded:: 7.2
+
+    The support for the ``'PRIVATE_SUBNETS'`` string was introduced in Symfony 7.2.
+
 That's it! It's critical that you prevent traffic from all non-trusted sources.
 If you allow outside traffic, they could "spoof" their true IP address and
 other information.

From 2e118366f2008a899da6adb7178a4db280d2548f Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Wed, 11 Sep 2024 08:42:14 +0200
Subject: [PATCH 351/747] [Emoji][String] Extract Emoji from String
 documentation

---
 components/intl.rst |   2 +-
 emoji.rst           | 143 ++++++++++++++++++++++++++++++++++++
 string.rst          | 174 +-------------------------------------------
 3 files changed, 145 insertions(+), 174 deletions(-)
 create mode 100644 emoji.rst

diff --git a/components/intl.rst b/components/intl.rst
index 008d9161fd7..ba3cbdcb959 100644
--- a/components/intl.rst
+++ b/components/intl.rst
@@ -386,7 +386,7 @@ Emoji Transliteration
 ~~~~~~~~~~~~~~~~~~~~~
 
 Symfony provides utilities to translate emojis into their textual representation
-in all languages. Read the documentation on :ref:`working with emojis in strings <string-emoji-transliteration>`
+in all languages. Read the documentation about :ref:`emoji transliteration <emoji-transliteration>`
 to learn more about this feature.
 
 Disk Space
diff --git a/emoji.rst b/emoji.rst
new file mode 100644
index 00000000000..ba6ca38ed73
--- /dev/null
+++ b/emoji.rst
@@ -0,0 +1,143 @@
+Working with Emojis
+===================
+
+.. versionadded:: 7.1
+
+    The emoji component was introduced in Symfony 7.1.
+
+Symfony provides several utilities to work with emoji characters and sequences
+from the `Unicode CLDR dataset`_. They are available via the Emoji component,
+which you must first install in your application:
+
+.. _installation:
+
+.. code-block:: terminal
+
+    $ composer require symfony/emoji
+
+.. include:: /components/require_autoload.rst.inc
+
+The data needed to store the transliteration of all emojis (~5,000) into all
+languages take a considerable disk space.
+
+If you need to save disk space (e.g. because you deploy to some service with tight
+size constraints), run this command (e.g. as an automated script after ``composer install``)
+to compress the internal Symfony emoji data files using the PHP ``zlib`` extension:
+
+.. code-block:: terminal
+
+    # adjust the path to the 'compress' binary based on your application installation
+    $ php ./vendor/symfony/emoji/Resources/bin/compress
+
+.. _emoji-transliteration:
+
+Emoji Transliteration
+~~~~~~~~~~~~~~~~~~~~~
+
+The ``EmojiTransliterator`` class offers a way to translate emojis into their
+textual representation in all languages based on the `Unicode CLDR dataset`_::
+
+    use Symfony\Component\Emoji\EmojiTransliterator;
+
+    // Describe emojis in English
+    $transliterator = EmojiTransliterator::create('en');
+    $transliterator->transliterate('Menus with 🍕 or 🍝');
+    // => 'Menus with pizza or spaghetti'
+
+    // Describe emojis in Ukrainian
+    $transliterator = EmojiTransliterator::create('uk');
+    $transliterator->transliterate('Menus with 🍕 or 🍝');
+    // => 'Menus with піца or спагеті'
+
+You can also combine the ``EmojiTransliterator`` with the :ref:`slugger <string-slugger-emoji>`
+to transform any emojis into their textual representation.
+
+Transliterating Emoji Text Short Codes
+......................................
+
+Services like GitHub and Slack allows to include emojis in your messages using
+text short codes (e.g. you can add the ``:+1:`` code to render the 👍 emoji).
+
+Symfony also provides a feature to transliterate emojis into short codes and vice
+versa. The short codes are slightly different on each service, so you must pass
+the name of the service as an argument when creating the transliterator.
+
+Convert emojis to GitHub short codes with the ``emoji-github`` locale::
+
+    $transliterator = EmojiTransliterator::create('emoji-github');
+    $transliterator->transliterate('Teenage 🐢 really love 🍕');
+    // => 'Teenage :turtle: really love :pizza:'
+
+Convert GitHub short codes to emojis with the ``github-emoji`` locale::
+
+    $transliterator = EmojiTransliterator::create('github-emoji');
+    $transliterator->transliterate('Teenage :turtle: really love :pizza:');
+    // => 'Teenage 🐢 really love 🍕'
+
+.. note::
+
+    Github, Gitlab and Slack are currently available services in
+    ``EmojiTransliterator``.
+
+.. _text-emoji:
+
+Universal Emoji Short Codes Transliteration
+###########################################
+
+If you don't know which service was used to generate the short codes, you can use
+the ``text-emoji`` locale, which combines all codes from all services::
+
+    $transliterator = EmojiTransliterator::create('text-emoji');
+
+    // Github short codes
+    $transliterator->transliterate('Breakfast with :kiwi-fruit: or :milk-glass:');
+    // Gitlab short codes
+    $transliterator->transliterate('Breakfast with :kiwi: or :milk:');
+    // Slack short codes
+    $transliterator->transliterate('Breakfast with :kiwifruit: or :glass-of-milk:');
+
+    // all the above examples produce the same result:
+    // => 'Breakfast with 🥝 or 🥛'
+
+You can convert emojis to short codes with the ``emoji-text`` locale::
+
+    $transliterator = EmojiTransliterator::create('emoji-text');
+    $transliterator->transliterate('Breakfast with 🥝 or 🥛');
+    // => 'Breakfast with :kiwifruit: or :milk-glass:
+
+Inverse Emoji Transliteration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Given the textual representation of an emoji, you can reverse it back to get the
+actual emoji thanks to the :ref:`emojify filter <reference-twig-filter-emojify>`:
+
+.. code-block:: twig
+
+    {{ 'I like :kiwi-fruit:'|emojify }} {# renders: I like 🥝 #}
+    {{ 'I like :kiwi:'|emojify }}       {# renders: I like 🥝 #}
+    {{ 'I like :kiwifruit:'|emojify }}  {# renders: I like 🥝 #}
+
+By default, ``emojify`` uses the :ref:`text catalog <text-emoji>`, which
+merges the emoji text codes of all services. If you prefer, you can select a
+specific catalog to use:
+
+.. code-block:: twig
+
+    {{ 'I :green-heart: this'|emojify }}                  {# renders: I 💚 this #}
+    {{ ':green_salad: is nice'|emojify('slack') }}        {# renders: 🥗 is nice #}
+    {{ 'My :turtle: has no name yet'|emojify('github') }} {# renders: My 🐢 has no name yet #}
+    {{ ':kiwi: is a great fruit'|emojify('gitlab') }}     {# renders: 🥝 is a great fruit #}
+
+Removing Emojis
+~~~~~~~~~~~~~~~
+
+The ``EmojiTransliterator`` can also be used to remove all emojis from a string,
+via the special ``strip`` locale::
+
+    use Symfony\Component\Emoji\EmojiTransliterator;
+
+    $transliterator = EmojiTransliterator::create('strip');
+    $transliterator->transliterate('🎉Hey!🥳 🎁Happy Birthday!🎁');
+    // => 'Hey! Happy Birthday!'
+
+.. _`Unicode CLDR dataset`: https://github.com/unicode-org/cldr
diff --git a/string.rst b/string.rst
index 5e18cfcaea3..702e9344880 100644
--- a/string.rst
+++ b/string.rst
@@ -507,177 +507,6 @@ requested during the program execution. You can also create lazy strings from a
     // hash computation only if it's needed
     $lazyHash = LazyString::fromStringable(new Hash());
 
-.. _working-with-emojis:
-
-Working with Emojis
--------------------
-
-.. versionadded:: 7.1
-
-    The emoji component was introduced in Symfony 7.1.
-
-Symfony provides several utilities to work with emoji characters and sequences
-from the `Unicode CLDR dataset`_. They are available via the Emoji component,
-which you must first install in your application:
-
-.. code-block:: terminal
-
-    $ composer require symfony/emoji
-
-.. include:: /components/require_autoload.rst.inc
-
-The data needed to store the transliteration of all emojis (~5,000) into all
-languages take a considerable disk space.
-
-If you need to save disk space (e.g. because you deploy to some service with tight
-size constraints), run this command (e.g. as an automated script after ``composer install``)
-to compress the internal Symfony emoji data files using the PHP ``zlib`` extension:
-
-.. code-block:: terminal
-
-    # adjust the path to the 'compress' binary based on your application installation
-    $ php ./vendor/symfony/emoji/Resources/bin/compress
-
-.. _string-emoji-transliteration:
-
-Emoji Transliteration
-~~~~~~~~~~~~~~~~~~~~~
-
-The ``EmojiTransliterator`` class offers a way to translate emojis into their
-textual representation in all languages based on the `Unicode CLDR dataset`_::
-
-    use Symfony\Component\Emoji\EmojiTransliterator;
-
-    // Describe emojis in English
-    $transliterator = EmojiTransliterator::create('en');
-    $transliterator->transliterate('Menus with 🍕 or 🍝');
-    // => 'Menus with pizza or spaghetti'
-
-    // Describe emojis in Ukrainian
-    $transliterator = EmojiTransliterator::create('uk');
-    $transliterator->transliterate('Menus with 🍕 or 🍝');
-    // => 'Menus with піца or спагеті'
-
-Transliterating Emoji Text Short Codes
-......................................
-
-Services like GitHub and Slack allows to include emojis in your messages using
-text short codes (e.g. you can add the ``:+1:`` code to render the 👍 emoji).
-
-Symfony also provides a feature to transliterate emojis into short codes and vice
-versa. The short codes are slightly different on each service, so you must pass
-the name of the service as an argument when creating the transliterator:
-
-GitHub Emoji Short Codes Transliteration
-########################################
-
-Convert emojis to GitHub short codes with the ``emoji-github`` locale::
-
-    $transliterator = EmojiTransliterator::create('emoji-github');
-    $transliterator->transliterate('Teenage 🐢 really love 🍕');
-    // => 'Teenage :turtle: really love :pizza:'
-
-Convert GitHub short codes to emojis with the ``github-emoji`` locale::
-
-    $transliterator = EmojiTransliterator::create('github-emoji');
-    $transliterator->transliterate('Teenage :turtle: really love :pizza:');
-    // => 'Teenage 🐢 really love 🍕'
-
-Gitlab Emoji Short Codes Transliteration
-########################################
-
-Convert emojis to Gitlab short codes with the ``emoji-gitlab`` locale::
-
-    $transliterator = EmojiTransliterator::create('emoji-gitlab');
-    $transliterator->transliterate('Breakfast with 🥝 or 🥛');
-    // => 'Breakfast with :kiwi: or :milk:'
-
-Convert Gitlab short codes to emojis with the ``gitlab-emoji`` locale::
-
-    $transliterator = EmojiTransliterator::create('gitlab-emoji');
-    $transliterator->transliterate('Breakfast with :kiwi: or :milk:');
-    // => 'Breakfast with 🥝 or 🥛'
-
-Slack Emoji Short Codes Transliteration
-#######################################
-
-Convert emojis to Slack short codes with the ``emoji-slack`` locale::
-
-    $transliterator = EmojiTransliterator::create('emoji-slack');
-    $transliterator->transliterate('Menus with 🥗 or 🧆');
-    // => 'Menus with :green_salad: or :falafel:'
-
-Convert Slack short codes to emojis with the ``slack-emoji`` locale::
-
-    $transliterator = EmojiTransliterator::create('slack-emoji');
-    $transliterator->transliterate('Menus with :green_salad: or :falafel:');
-    // => 'Menus with 🥗 or 🧆'
-
-.. _string-text-emoji:
-
-Universal Emoji Short Codes Transliteration
-###########################################
-
-If you don't know which service was used to generate the short codes, you can use
-the ``text-emoji`` locale, which combines all codes from all services::
-
-    $transliterator = EmojiTransliterator::create('text-emoji');
-
-    // Github short codes
-    $transliterator->transliterate('Breakfast with :kiwi-fruit: or :milk-glass:');
-    // Gitlab short codes
-    $transliterator->transliterate('Breakfast with :kiwi: or :milk:');
-    // Slack short codes
-    $transliterator->transliterate('Breakfast with :kiwifruit: or :glass-of-milk:');
-
-    // all the above examples produce the same result:
-    // => 'Breakfast with 🥝 or 🥛'
-
-You can convert emojis to short codes with the ``emoji-text`` locale::
-
-    $transliterator = EmojiTransliterator::create('emoji-text');
-    $transliterator->transliterate('Breakfast with 🥝 or 🥛');
-    // => 'Breakfast with :kiwifruit: or :milk-glass:
-
-Inverse Emoji Transliteration
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. versionadded:: 7.1
-
-    The inverse emoji transliteration was introduced in Symfony 7.1.
-
-Given the textual representation of an emoji, you can reverse it back to get the
-actual emoji thanks to the :ref:`emojify filter <reference-twig-filter-emojify>`:
-
-.. code-block:: twig
-
-    {{ 'I like :kiwi-fruit:'|emojify }} {# renders: I like 🥝 #}
-    {{ 'I like :kiwi:'|emojify }}       {# renders: I like 🥝 #}
-    {{ 'I like :kiwifruit:'|emojify }}  {# renders: I like 🥝 #}
-
-By default, ``emojify`` uses the :ref:`text catalog <string-text-emoji>`, which
-merges the emoji text codes of all services. If you prefer, you can select a
-specific catalog to use:
-
-.. code-block:: twig
-
-    {{ 'I :green-heart: this'|emojify }}                  {# renders: I 💚 this #}
-    {{ ':green_salad: is nice'|emojify('slack') }}        {# renders: 🥗 is nice #}
-    {{ 'My :turtle: has no name yet'|emojify('github') }} {# renders: My 🐢 has no name yet #}
-    {{ ':kiwi: is a great fruit'|emojify('gitlab') }}     {# renders: 🥝 is a great fruit #}
-
-Removing Emojis
-~~~~~~~~~~~~~~~
-
-The ``EmojiTransliterator`` can also be used to remove all emojis from a string,
-via the special ``strip`` locale::
-
-    use Symfony\Component\Emoji\EmojiTransliterator;
-
-    $transliterator = EmojiTransliterator::create('strip');
-    $transliterator->transliterate('🎉Hey!🥳 🎁Happy Birthday!🎁');
-    // => 'Hey! Happy Birthday!'
-
 .. _string-slugger:
 
 Slugger
@@ -752,7 +581,7 @@ the injected slugger is the same as the request locale::
 Slug Emojis
 ~~~~~~~~~~~
 
-You can also combine the :ref:`emoji transliterator <string-emoji-transliteration>`
+You can also combine the :ref:`emoji transliterator <emoji-transliteration>`
 with the slugger to transform any emojis into their textual representation::
 
     use Symfony\Component\String\Slugger\AsciiSlugger;
@@ -822,4 +651,3 @@ possible to determine a unique singular/plural form for the given word.
 .. _`Code points`: https://en.wikipedia.org/wiki/Code_point
 .. _`Grapheme clusters`: https://en.wikipedia.org/wiki/Grapheme
 .. _`Unicode equivalence`: https://en.wikipedia.org/wiki/Unicode_equivalence
-.. _`Unicode CLDR dataset`: https://github.com/unicode-org/cldr

From add4600eab9d96b52a44eae81f35904c45e23e92 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 19 Sep 2024 17:31:06 +0200
Subject: [PATCH 352/747] Minor tweaks

---
 emoji.rst | 50 ++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 40 insertions(+), 10 deletions(-)

diff --git a/emoji.rst b/emoji.rst
index ba6ca38ed73..551497f0c76 100644
--- a/emoji.rst
+++ b/emoji.rst
@@ -32,7 +32,7 @@ to compress the internal Symfony emoji data files using the PHP ``zlib`` extensi
 .. _emoji-transliteration:
 
 Emoji Transliteration
-~~~~~~~~~~~~~~~~~~~~~
+---------------------
 
 The ``EmojiTransliterator`` class offers a way to translate emojis into their
 textual representation in all languages based on the `Unicode CLDR dataset`_::
@@ -49,11 +49,13 @@ textual representation in all languages based on the `Unicode CLDR dataset`_::
     $transliterator->transliterate('Menus with 🍕 or 🍝');
     // => 'Menus with піца or спагеті'
 
-You can also combine the ``EmojiTransliterator`` with the :ref:`slugger <string-slugger-emoji>`
-to transform any emojis into their textual representation.
+.. tip::
+
+    When using the :ref:`slugger <string-slugger>` from the String component,
+    you can combine it with the ``EmojiTransliterator`` to :ref:`slugify emojis <string-slugger-emoji>`.
 
 Transliterating Emoji Text Short Codes
-......................................
+--------------------------------------
 
 Services like GitHub and Slack allows to include emojis in your messages using
 text short codes (e.g. you can add the ``:+1:`` code to render the 👍 emoji).
@@ -62,6 +64,9 @@ Symfony also provides a feature to transliterate emojis into short codes and vic
 versa. The short codes are slightly different on each service, so you must pass
 the name of the service as an argument when creating the transliterator.
 
+GitHub Emoji Short Codes Transliteration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 Convert emojis to GitHub short codes with the ``emoji-github`` locale::
 
     $transliterator = EmojiTransliterator::create('emoji-github');
@@ -74,15 +79,40 @@ Convert GitHub short codes to emojis with the ``github-emoji`` locale::
     $transliterator->transliterate('Teenage :turtle: really love :pizza:');
     // => 'Teenage 🐢 really love 🍕'
 
-.. note::
+Gitlab Emoji Short Codes Transliteration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Convert emojis to Gitlab short codes with the ``emoji-gitlab`` locale::
+
+    $transliterator = EmojiTransliterator::create('emoji-gitlab');
+    $transliterator->transliterate('Breakfast with 🥝 or 🥛');
+    // => 'Breakfast with :kiwi: or :milk:'
+
+Convert Gitlab short codes to emojis with the ``gitlab-emoji`` locale::
+
+    $transliterator = EmojiTransliterator::create('gitlab-emoji');
+    $transliterator->transliterate('Breakfast with :kiwi: or :milk:');
+    // => 'Breakfast with 🥝 or 🥛'
+
+Slack Emoji Short Codes Transliteration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Convert emojis to Slack short codes with the ``emoji-slack`` locale::
+
+    $transliterator = EmojiTransliterator::create('emoji-slack');
+    $transliterator->transliterate('Menus with 🥗 or 🧆');
+    // => 'Menus with :green_salad: or :falafel:'
+
+Convert Slack short codes to emojis with the ``slack-emoji`` locale::
 
-    Github, Gitlab and Slack are currently available services in
-    ``EmojiTransliterator``.
+    $transliterator = EmojiTransliterator::create('slack-emoji');
+    $transliterator->transliterate('Menus with :green_salad: or :falafel:');
+    // => 'Menus with 🥗 or 🧆'
 
 .. _text-emoji:
 
 Universal Emoji Short Codes Transliteration
-###########################################
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 If you don't know which service was used to generate the short codes, you can use
 the ``text-emoji`` locale, which combines all codes from all services::
@@ -106,7 +136,7 @@ You can convert emojis to short codes with the ``emoji-text`` locale::
     // => 'Breakfast with :kiwifruit: or :milk-glass:
 
 Inverse Emoji Transliteration
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-----------------------------
 
 Given the textual representation of an emoji, you can reverse it back to get the
 actual emoji thanks to the :ref:`emojify filter <reference-twig-filter-emojify>`:
@@ -129,7 +159,7 @@ specific catalog to use:
     {{ ':kiwi: is a great fruit'|emojify('gitlab') }}     {# renders: 🥝 is a great fruit #}
 
 Removing Emojis
-~~~~~~~~~~~~~~~
+---------------
 
 The ``EmojiTransliterator`` can also be used to remove all emojis from a string,
 via the special ``strip`` locale::

From 7815198fe2e3b58229650e022cd8c89cb53c1568 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 19 Sep 2024 17:33:25 +0200
Subject: [PATCH 353/747] [String] Added a message about the moved Emoji docs

---
 string.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/string.rst b/string.rst
index 702e9344880..667dcd06010 100644
--- a/string.rst
+++ b/string.rst
@@ -507,6 +507,11 @@ requested during the program execution. You can also create lazy strings from a
     // hash computation only if it's needed
     $lazyHash = LazyString::fromStringable(new Hash());
 
+Working with Emojis
+-------------------
+
+These contents have been moved to the :doc:`Emoji component docs </emoji>`.
+
 .. _string-slugger:
 
 Slugger

From 7573d4a1211c81ae08d2ca26df5311322c45bb0b Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Thu, 19 Sep 2024 10:11:30 +0200
Subject: [PATCH 354/747] [Security] Allow passport attributes in
 `Security::login()`

---
 security.rst | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/security.rst b/security.rst
index a8aa652a222..51ee9b5c3fb 100644
--- a/security.rst
+++ b/security.rst
@@ -1767,9 +1767,12 @@ You can log in a user programmatically using the ``login()`` method of the
             // you can also log in on a different firewall...
             $security->login($user, 'form_login', 'other_firewall');
 
-            // ...and add badges
+            // ... add badges...
             $security->login($user, 'form_login', 'other_firewall', [(new RememberMeBadge())->enable()]);
 
+            // ... and also add passport attributes
+            $security->login($user, 'form_login', 'other_firewall', [(new RememberMeBadge())->enable()], ['referer' => 'https://oauth.example.com']);
+
             // use the redirection logic applied to regular login
             $redirectResponse = $security->login($user);
             return $redirectResponse;
@@ -1779,6 +1782,12 @@ You can log in a user programmatically using the ``login()`` method of the
         }
     }
 
+.. versionadded:: 7.2
+
+    The support for passport attributes in the
+    :method:`Symfony\\Bundle\\SecurityBundle\\Security::login` method was
+    introduced in Symfony 7.2.
+
 .. _security-logging-out:
 
 Logging Out

From b0a91ce7a24f40b52d6732d32fc1dad28043a964 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 19 Sep 2024 09:00:51 +0200
Subject: [PATCH 355/747] [String] Document the Spanish inflector

---
 string.rst | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/string.rst b/string.rst
index f2856976986..cb822e1dbd1 100644
--- a/string.rst
+++ b/string.rst
@@ -820,11 +820,28 @@ class to convert English words from/to singular/plural with confidence::
 The value returned by both methods is always an array because sometimes it's not
 possible to determine a unique singular/plural form for the given word.
 
+Symfony also provides inflectors for other languages::
+
+    use Symfony\Component\String\Inflector\FrenchInflector;
+
+    $inflector = new FrenchInflector();
+    $result = $inflector->singularize('souris'); // ['souris']
+    $result = $inflector->pluralize('hôpital');  // ['hôpitaux']
+
+    use Symfony\Component\String\Inflector\SpanishInflector;
+
+    $inflector = new SpanishInflector();
+    $result = $inflector->singularize('aviones'); // ['avión']
+    $result = $inflector->pluralize('miércoles'); // ['miércoles']
+
+.. versionadded:: 7.2
+
+    The ``SpanishInflector`` class was introduced in Symfony 7.2.
+
 .. note::
 
-    Symfony also provides a :class:`Symfony\\Component\\String\\Inflector\\FrenchInflector`
-    and an :class:`Symfony\\Component\\String\\Inflector\\InflectorInterface` if
-    you need to implement your own inflector.
+    Symfony provides a :class:`Symfony\\Component\\String\\Inflector\\InflectorInterface`
+    in case you need to implement your own inflector.
 
 .. _`ASCII`: https://en.wikipedia.org/wiki/ASCII
 .. _`Unicode`: https://en.wikipedia.org/wiki/Unicode

From 3983e81d511ced672866601c191f4ec780492634 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Fri, 20 Sep 2024 16:59:19 +0200
Subject: [PATCH 356/747] fix typo

---
 string.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/string.rst b/string.rst
index da82791c740..37f64bc4f3b 100644
--- a/string.rst
+++ b/string.rst
@@ -674,7 +674,7 @@ Symfony also provides inflectors for other languages::
 
 .. note::
 
-    Symfony provides a :class:`Symfony\\Component\\String\\Inflector\\InflectorInterface`
+    Symfony provides an :class:`Symfony\\Component\\String\\Inflector\\InflectorInterface`
     in case you need to implement your own inflector.
 
 .. _`ASCII`: https://en.wikipedia.org/wiki/ASCII

From fdda76fe73d83158eba51bbff5798ddd38ccf1ef Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 19 Sep 2024 12:41:59 +0200
Subject: [PATCH 357/747] [FrameworkBundle] Document the `resolve-env-vars`
 option of `lint:container` command

---
 service_container.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/service_container.rst b/service_container.rst
index 9e1cdff2098..f329587eb54 100644
--- a/service_container.rst
+++ b/service_container.rst
@@ -1069,6 +1069,14 @@ application to production (e.g. in your continuous integration server):
 
     $ php bin/console lint:container
 
+    # optionally, you can force the resolution of environment variables;
+    # the command will fail if any of those environment variables are missing
+    $ php bin/console lint:container --resolve-env-vars
+
+.. versionadded:: 7.2
+
+    The ``--resolve-env-vars`` option was introduced in Symfony 7.2.
+
 Performing those checks whenever the container is compiled can hurt performance.
 That's why they are implemented in :doc:`compiler passes </service_container/compiler_passes>`
 called ``CheckTypeDeclarationsPass`` and ``CheckAliasValidityPass``, which are

From a78ff470d7019a3cbf550ed3a7412340e18992e7 Mon Sep 17 00:00:00 2001
From: Yonel Ceruto <yonel.ceruto@scnd.com>
Date: Sun, 22 Sep 2024 11:34:16 -0400
Subject: [PATCH 358/747] documenting non-empty parameters

---
 configuration.rst | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/configuration.rst b/configuration.rst
index 36dceae1b71..52dc9b98c95 100644
--- a/configuration.rst
+++ b/configuration.rst
@@ -382,6 +382,25 @@ a new ``locale`` parameter is added to the ``config/services.yaml`` file).
     They are useful when working with :ref:`Compiler Passes </service_container/compiler_passes>`
     to declare some temporary parameters that won't be available later in the application.
 
+Configuration parameters are usually validation-free, but you can ensure that
+essential parameters for your application's functionality are not empty::
+
+    // ContainerBuilder
+    $container->parameterCannotBeEmpty('app.private_key', 'Did you forget to configure a non-empty value for "app.private_key" parameter?');
+
+If a non-empty parameter is ``null``, an empty string ``''``, or an empty array ``[]``,
+Symfony will throw an exception with the custom error message when attempting to
+retrieve the value of this parameter.
+
+.. versionadded:: 7.2
+
+    Validating non-empty parameters was introduced in Symfony 7.2.
+
+.. note::
+
+    Please note that this validation will *only* occur if a non-empty parameter value
+    is retrieved; otherwise, no exception will be thrown.
+
 .. seealso::
 
     Later in this article you can read how to

From 6516a9b4bcd72535bc566686284596b4b85a082d Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Tue, 24 Sep 2024 10:49:35 +0200
Subject: [PATCH 359/747] form/remove-legacy-message

---
 reference/forms/types/birthday.rst     | 2 --
 reference/forms/types/checkbox.rst     | 2 --
 reference/forms/types/choice.rst       | 2 --
 reference/forms/types/collection.rst   | 2 --
 reference/forms/types/color.rst        | 2 --
 reference/forms/types/country.rst      | 2 --
 reference/forms/types/currency.rst     | 2 --
 reference/forms/types/date.rst         | 2 --
 reference/forms/types/dateinterval.rst | 2 --
 reference/forms/types/datetime.rst     | 2 --
 reference/forms/types/email.rst        | 2 --
 reference/forms/types/enum.rst         | 2 --
 reference/forms/types/file.rst         | 2 --
 reference/forms/types/form.rst         | 2 --
 reference/forms/types/hidden.rst       | 2 --
 reference/forms/types/integer.rst      | 2 --
 reference/forms/types/language.rst     | 2 --
 reference/forms/types/locale.rst       | 2 --
 reference/forms/types/money.rst        | 2 --
 reference/forms/types/number.rst       | 2 --
 reference/forms/types/password.rst     | 2 --
 reference/forms/types/percent.rst      | 2 --
 reference/forms/types/radio.rst        | 2 --
 reference/forms/types/range.rst        | 2 --
 reference/forms/types/repeated.rst     | 2 --
 reference/forms/types/search.rst       | 2 --
 reference/forms/types/tel.rst          | 2 --
 reference/forms/types/time.rst         | 2 --
 reference/forms/types/timezone.rst     | 2 --
 reference/forms/types/ulid.rst         | 2 --
 reference/forms/types/url.rst          | 2 --
 reference/forms/types/uuid.rst         | 2 --
 reference/forms/types/week.rst         | 2 --
 33 files changed, 66 deletions(-)

diff --git a/reference/forms/types/birthday.rst b/reference/forms/types/birthday.rst
index 2098d3cfb89..383dbf890f2 100644
--- a/reference/forms/types/birthday.rst
+++ b/reference/forms/types/birthday.rst
@@ -19,8 +19,6 @@ option defaults to 120 years ago to the current year.
 +---------------------------+-------------------------------------------------------------------------------+
 | Default invalid message   | Please enter a valid birthdate.                                               |
 +---------------------------+-------------------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                           |
-+---------------------------+-------------------------------------------------------------------------------+
 | Parent type               | :doc:`DateType </reference/forms/types/date>`                                 |
 +---------------------------+-------------------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\BirthdayType`        |
diff --git a/reference/forms/types/checkbox.rst b/reference/forms/types/checkbox.rst
index 472d6f84024..2299220c5b6 100644
--- a/reference/forms/types/checkbox.rst
+++ b/reference/forms/types/checkbox.rst
@@ -13,8 +13,6 @@ if you want to handle submitted values like "0" or "false").
 +---------------------------+------------------------------------------------------------------------+
 | Default invalid message   | The checkbox has an invalid value.                                     |
 +---------------------------+------------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                    |
-+---------------------------+------------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                          |
 +---------------------------+------------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\CheckboxType` |
diff --git a/reference/forms/types/choice.rst b/reference/forms/types/choice.rst
index 0b250b799da..55f2d016001 100644
--- a/reference/forms/types/choice.rst
+++ b/reference/forms/types/choice.rst
@@ -11,8 +11,6 @@ To use this field, you must specify *either* ``choices`` or ``choice_loader`` op
 +---------------------------+----------------------------------------------------------------------+
 | Default invalid message   | The selected choice is invalid.                                      |
 +---------------------------+----------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                  |
-+---------------------------+----------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                        |
 +---------------------------+----------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\ChoiceType` |
diff --git a/reference/forms/types/collection.rst b/reference/forms/types/collection.rst
index acb110fd722..c5fee42f06c 100644
--- a/reference/forms/types/collection.rst
+++ b/reference/forms/types/collection.rst
@@ -16,8 +16,6 @@ that is passed as the collection type field data.
 +---------------------------+--------------------------------------------------------------------------+
 | Default invalid message   | The collection is invalid.                                               |
 +---------------------------+--------------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                      |
-+---------------------------+--------------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                            |
 +---------------------------+--------------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\CollectionType` |
diff --git a/reference/forms/types/color.rst b/reference/forms/types/color.rst
index 1a320b9bdbf..b205127fb91 100644
--- a/reference/forms/types/color.rst
+++ b/reference/forms/types/color.rst
@@ -16,8 +16,6 @@ element.
 +---------------------------+---------------------------------------------------------------------+
 | Default invalid message   | Please select a valid color.                                        |
 +---------------------------+---------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                 |
-+---------------------------+---------------------------------------------------------------------+
 | Parent type               | :doc:`TextType </reference/forms/types/text>`                       |
 +---------------------------+---------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\ColorType` |
diff --git a/reference/forms/types/country.rst b/reference/forms/types/country.rst
index 8913e639f23..d841461b2f5 100644
--- a/reference/forms/types/country.rst
+++ b/reference/forms/types/country.rst
@@ -20,8 +20,6 @@ the option manually, but then you should just use the ``ChoiceType`` directly.
 +---------------------------+-----------------------------------------------------------------------+
 | Default invalid message   | Please select a valid country.                                        |
 +---------------------------+-----------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                   |
-+---------------------------+-----------------------------------------------------------------------+
 | Parent type               | :doc:`ChoiceType </reference/forms/types/choice>`                     |
 +---------------------------+-----------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\CountryType` |
diff --git a/reference/forms/types/currency.rst b/reference/forms/types/currency.rst
index cca441ff930..b69225eb78c 100644
--- a/reference/forms/types/currency.rst
+++ b/reference/forms/types/currency.rst
@@ -13,8 +13,6 @@ manually, but then you should just use the ``ChoiceType`` directly.
 +---------------------------+------------------------------------------------------------------------+
 | Default invalid message   | Please select a valid currency.                                        |
 +---------------------------+------------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                    |
-+---------------------------+------------------------------------------------------------------------+
 | Parent type               | :doc:`ChoiceType </reference/forms/types/choice>`                      |
 +---------------------------+------------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\CurrencyType` |
diff --git a/reference/forms/types/date.rst b/reference/forms/types/date.rst
index 515c12099a1..c412872442e 100644
--- a/reference/forms/types/date.rst
+++ b/reference/forms/types/date.rst
@@ -14,8 +14,6 @@ and can understand a number of different input formats via the `input`_ option.
 +---------------------------+-----------------------------------------------------------------------------+
 | Default invalid message   | Please enter a valid date.                                                  |
 +---------------------------+-----------------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                         |
-+---------------------------+-----------------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                               |
 +---------------------------+-----------------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\DateType`          |
diff --git a/reference/forms/types/dateinterval.rst b/reference/forms/types/dateinterval.rst
index 627fb78d7ed..38fccb47cd1 100644
--- a/reference/forms/types/dateinterval.rst
+++ b/reference/forms/types/dateinterval.rst
@@ -16,8 +16,6 @@ or an array (see `input`_).
 +---------------------------+----------------------------------------------------------------------------------+
 | Default invalid message   | Please choose a valid date interval.                                             |
 +---------------------------+----------------------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                              |
-+---------------------------+----------------------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                                    |
 +---------------------------+----------------------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\DateIntervalType`       |
diff --git a/reference/forms/types/datetime.rst b/reference/forms/types/datetime.rst
index 7ffc0ee216f..5fda8e9a14f 100644
--- a/reference/forms/types/datetime.rst
+++ b/reference/forms/types/datetime.rst
@@ -14,8 +14,6 @@ the data can be a ``DateTime`` object, a string, a timestamp or an array.
 +---------------------------+-----------------------------------------------------------------------------+
 | Default invalid message   | Please enter a valid date and time.                                         |
 +---------------------------+-----------------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                         |
-+---------------------------+-----------------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                               |
 +---------------------------+-----------------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\DateTimeType`      |
diff --git a/reference/forms/types/email.rst b/reference/forms/types/email.rst
index 9045bba8cc4..ef535050813 100644
--- a/reference/forms/types/email.rst
+++ b/reference/forms/types/email.rst
@@ -9,8 +9,6 @@ The ``EmailType`` field is a text field that is rendered using the HTML5
 +---------------------------+---------------------------------------------------------------------+
 | Default invalid message   | Please enter a valid email address.                                 |
 +---------------------------+---------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                 |
-+---------------------------+---------------------------------------------------------------------+
 | Parent type               | :doc:`TextType </reference/forms/types/text>`                       |
 +---------------------------+---------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\EmailType` |
diff --git a/reference/forms/types/enum.rst b/reference/forms/types/enum.rst
index 0aad19767e3..875c0808108 100644
--- a/reference/forms/types/enum.rst
+++ b/reference/forms/types/enum.rst
@@ -10,8 +10,6 @@ field and defines the same options.
 +---------------------------+----------------------------------------------------------------------+
 | Default invalid message   | The selected choice is invalid.                                      |
 +---------------------------+----------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                  |
-+---------------------------+----------------------------------------------------------------------+
 | Parent type               | :doc:`ChoiceType </reference/forms/types/choice>`                    |
 +---------------------------+----------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\EnumType`   |
diff --git a/reference/forms/types/file.rst b/reference/forms/types/file.rst
index b4982859b98..2e841611eb8 100644
--- a/reference/forms/types/file.rst
+++ b/reference/forms/types/file.rst
@@ -8,8 +8,6 @@ The ``FileType`` represents a file input in your form.
 +---------------------------+--------------------------------------------------------------------+
 | Default invalid message   | Please select a valid file.                                        |
 +---------------------------+--------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                |
-+---------------------------+--------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                      |
 +---------------------------+--------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\FileType` |
diff --git a/reference/forms/types/form.rst b/reference/forms/types/form.rst
index 0d0089c1fd3..58a6214d379 100644
--- a/reference/forms/types/form.rst
+++ b/reference/forms/types/form.rst
@@ -7,8 +7,6 @@ on all types for which ``FormType`` is the parent.
 +---------------------------+--------------------------------------------------------------------+
 | Default invalid message   | This value is not valid.                                           |
 +---------------------------+--------------------------------------------------------------------+
-| Legacy invalid message    | This value is not valid.                                           |
-+---------------------------+--------------------------------------------------------------------+
 | Parent                    | none                                                               |
 +---------------------------+--------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType` |
diff --git a/reference/forms/types/hidden.rst b/reference/forms/types/hidden.rst
index fba056b88e5..d6aff282edd 100644
--- a/reference/forms/types/hidden.rst
+++ b/reference/forms/types/hidden.rst
@@ -8,8 +8,6 @@ The hidden type represents a hidden input field.
 +---------------------------+----------------------------------------------------------------------+
 | Default invalid message   | The hidden field is invalid.                                         |
 +---------------------------+----------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                  |
-+---------------------------+----------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                        |
 +---------------------------+----------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\HiddenType` |
diff --git a/reference/forms/types/integer.rst b/reference/forms/types/integer.rst
index 619ac996df6..1f94f9e2525 100644
--- a/reference/forms/types/integer.rst
+++ b/reference/forms/types/integer.rst
@@ -15,8 +15,6 @@ integers. By default, all non-integer values (e.g. 6.78) will round down
 +---------------------------+-----------------------------------------------------------------------+
 | Default invalid message   | Please enter an integer.                                              |
 +---------------------------+-----------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                   |
-+---------------------------+-----------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                         |
 +---------------------------+-----------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\IntegerType` |
diff --git a/reference/forms/types/language.rst b/reference/forms/types/language.rst
index 4b1bccd077d..e3dddfb8ae6 100644
--- a/reference/forms/types/language.rst
+++ b/reference/forms/types/language.rst
@@ -22,8 +22,6 @@ manually, but then you should just use the ``ChoiceType`` directly.
 +---------------------------+------------------------------------------------------------------------+
 | Default invalid message   | Please select a valid language.                                        |
 +---------------------------+------------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                    |
-+---------------------------+------------------------------------------------------------------------+
 | Parent type               | :doc:`ChoiceType </reference/forms/types/choice>`                      |
 +---------------------------+------------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\LanguageType` |
diff --git a/reference/forms/types/locale.rst b/reference/forms/types/locale.rst
index 1868f20eda1..68155a248fd 100644
--- a/reference/forms/types/locale.rst
+++ b/reference/forms/types/locale.rst
@@ -23,8 +23,6 @@ manually, but then you should just use the ``ChoiceType`` directly.
 +---------------------------+----------------------------------------------------------------------+
 | Default invalid message   | Please select a valid locale.                                        |
 +---------------------------+----------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                  |
-+---------------------------+----------------------------------------------------------------------+
 | Parent type               | :doc:`ChoiceType </reference/forms/types/choice>`                    |
 +---------------------------+----------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\LocaleType` |
diff --git a/reference/forms/types/money.rst b/reference/forms/types/money.rst
index 5793097fe2f..f9f8cefdd58 100644
--- a/reference/forms/types/money.rst
+++ b/reference/forms/types/money.rst
@@ -13,8 +13,6 @@ how the input and output of the data is handled.
 +---------------------------+---------------------------------------------------------------------+
 | Default invalid message   | Please enter a valid money amount.                                  |
 +---------------------------+---------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                 |
-+---------------------------+---------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                       |
 +---------------------------+---------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\MoneyType` |
diff --git a/reference/forms/types/number.rst b/reference/forms/types/number.rst
index 86d8eda3116..7e125a5fd05 100644
--- a/reference/forms/types/number.rst
+++ b/reference/forms/types/number.rst
@@ -10,8 +10,6 @@ that you want to use for your number.
 +---------------------------+----------------------------------------------------------------------+
 | Default invalid message   | Please enter a number.                                               |
 +---------------------------+----------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                  |
-+---------------------------+----------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                        |
 +---------------------------+----------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\NumberType` |
diff --git a/reference/forms/types/password.rst b/reference/forms/types/password.rst
index 7fb760471ef..83342194a4e 100644
--- a/reference/forms/types/password.rst
+++ b/reference/forms/types/password.rst
@@ -8,8 +8,6 @@ The ``PasswordType`` field renders an input password text box.
 +---------------------------+------------------------------------------------------------------------+
 | Default invalid message   | The password is invalid.                                               |
 +---------------------------+------------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                    |
-+---------------------------+------------------------------------------------------------------------+
 | Parent type               | :doc:`TextType </reference/forms/types/text>`                          |
 +---------------------------+------------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\PasswordType` |
diff --git a/reference/forms/types/percent.rst b/reference/forms/types/percent.rst
index ce985488c76..b46ca298c53 100644
--- a/reference/forms/types/percent.rst
+++ b/reference/forms/types/percent.rst
@@ -14,8 +14,6 @@ the input.
 +---------------------------+-----------------------------------------------------------------------+
 | Default invalid message   | Please enter a percentage value.                                      |
 +---------------------------+-----------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                   |
-+---------------------------+-----------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                         |
 +---------------------------+-----------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\PercentType` |
diff --git a/reference/forms/types/radio.rst b/reference/forms/types/radio.rst
index 7702b87cbad..7ab90086803 100644
--- a/reference/forms/types/radio.rst
+++ b/reference/forms/types/radio.rst
@@ -15,8 +15,6 @@ If you want to have a boolean field, use :doc:`CheckboxType </reference/forms/ty
 +---------------------------+---------------------------------------------------------------------+
 | Default invalid message   | Please select a valid option.                                       |
 +---------------------------+---------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                 |
-+---------------------------+---------------------------------------------------------------------+
 | Parent type               | :doc:`CheckboxType </reference/forms/types/checkbox>`               |
 +---------------------------+---------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\RadioType` |
diff --git a/reference/forms/types/range.rst b/reference/forms/types/range.rst
index 294023ce0c6..06eebfd5473 100644
--- a/reference/forms/types/range.rst
+++ b/reference/forms/types/range.rst
@@ -9,8 +9,6 @@ The ``RangeType`` field is a slider that is rendered using the HTML5
 +---------------------------+---------------------------------------------------------------------+
 | Default invalid message   | Please choose a valid range.                                        |
 +---------------------------+---------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                 |
-+---------------------------+---------------------------------------------------------------------+
 | Parent type               | :doc:`TextType </reference/forms/types/text>`                       |
 +---------------------------+---------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\RangeType` |
diff --git a/reference/forms/types/repeated.rst b/reference/forms/types/repeated.rst
index e5bd0cd4520..36211237bbd 100644
--- a/reference/forms/types/repeated.rst
+++ b/reference/forms/types/repeated.rst
@@ -11,8 +11,6 @@ accuracy.
 +---------------------------+------------------------------------------------------------------------+
 | Default invalid message   | The values do not match.                                               |
 +---------------------------+------------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                    |
-+---------------------------+------------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                          |
 +---------------------------+------------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\RepeatedType` |
diff --git a/reference/forms/types/search.rst b/reference/forms/types/search.rst
index e38021bc461..5ece0f6416b 100644
--- a/reference/forms/types/search.rst
+++ b/reference/forms/types/search.rst
@@ -11,8 +11,6 @@ Read about the input search field at `DiveIntoHTML5.info`_
 +---------------------------+----------------------------------------------------------------------+
 | Default invalid message   | Please enter a valid search term.                                    |
 +---------------------------+----------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                  |
-+---------------------------+----------------------------------------------------------------------+
 | Parent type               | :doc:`TextType </reference/forms/types/text>`                        |
 +---------------------------+----------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\SearchType` |
diff --git a/reference/forms/types/tel.rst b/reference/forms/types/tel.rst
index 675f8e3f5cd..e8ab9c322fe 100644
--- a/reference/forms/types/tel.rst
+++ b/reference/forms/types/tel.rst
@@ -15,8 +15,6 @@ to input phone numbers.
 +---------------------------+-------------------------------------------------------------------+
 | Default invalid message   | Please provide a valid phone number.                              |
 +---------------------------+-------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                               |
-+---------------------------+-------------------------------------------------------------------+
 | Parent type               | :doc:`TextType </reference/forms/types/text>`                     |
 +---------------------------+-------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\TelType` |
diff --git a/reference/forms/types/time.rst b/reference/forms/types/time.rst
index 2ce41c6ff74..43cf0644e0e 100644
--- a/reference/forms/types/time.rst
+++ b/reference/forms/types/time.rst
@@ -14,8 +14,6 @@ stored as a ``DateTime`` object, a string, a timestamp or an array.
 +---------------------------+-----------------------------------------------------------------------------+
 | Default invalid message   | Please enter a valid time.                                                  |
 +---------------------------+-----------------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                         |
-+---------------------------+-----------------------------------------------------------------------------+
 | Parent type               | FormType                                                                    |
 +---------------------------+-----------------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\TimeType`          |
diff --git a/reference/forms/types/timezone.rst b/reference/forms/types/timezone.rst
index 3750e1b98d8..7dae0f351b4 100644
--- a/reference/forms/types/timezone.rst
+++ b/reference/forms/types/timezone.rst
@@ -16,8 +16,6 @@ manually, but then you should just use the ``ChoiceType`` directly.
 +---------------------------+------------------------------------------------------------------------+
 | Default invalid message   | Please select a valid timezone.                                        |
 +---------------------------+------------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                    |
-+---------------------------+------------------------------------------------------------------------+
 | Parent type               | :doc:`ChoiceType </reference/forms/types/choice>`                      |
 +---------------------------+------------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\TimezoneType` |
diff --git a/reference/forms/types/ulid.rst b/reference/forms/types/ulid.rst
index 52bdb8eb136..71fb77cffa0 100644
--- a/reference/forms/types/ulid.rst
+++ b/reference/forms/types/ulid.rst
@@ -9,8 +9,6 @@ a proper :ref:`Ulid object <ulid>` when submitting the form.
 +---------------------------+-----------------------------------------------------------------------+
 | Default invalid message   | Please enter a valid ULID.                                            |
 +---------------------------+-----------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                   |
-+---------------------------+-----------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                         |
 +---------------------------+-----------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\UlidType`    |
diff --git a/reference/forms/types/url.rst b/reference/forms/types/url.rst
index 96984b23226..d4cb312d2bb 100644
--- a/reference/forms/types/url.rst
+++ b/reference/forms/types/url.rst
@@ -10,8 +10,6 @@ have a protocol.
 +---------------------------+-------------------------------------------------------------------+
 | Default invalid message   | Please enter a valid URL.                                         |
 +---------------------------+-------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                               |
-+---------------------------+-------------------------------------------------------------------+
 | Parent type               | :doc:`TextType </reference/forms/types/text>`                     |
 +---------------------------+-------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\UrlType` |
diff --git a/reference/forms/types/uuid.rst b/reference/forms/types/uuid.rst
index c5aa6c2fdde..664c446bba9 100644
--- a/reference/forms/types/uuid.rst
+++ b/reference/forms/types/uuid.rst
@@ -9,8 +9,6 @@ a proper :ref:`Uuid object <uuid>` when submitting the form.
 +---------------------------+-----------------------------------------------------------------------+
 | Default invalid message   | Please enter a valid UUID.                                            |
 +---------------------------+-----------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                   |
-+---------------------------+-----------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                         |
 +---------------------------+-----------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\UuidType`    |
diff --git a/reference/forms/types/week.rst b/reference/forms/types/week.rst
index 84ee98aff85..bcd39249015 100644
--- a/reference/forms/types/week.rst
+++ b/reference/forms/types/week.rst
@@ -14,8 +14,6 @@ the data can be a string or an array.
 +---------------------------+--------------------------------------------------------------------+
 | Default invalid message   | Please enter a valid week.                                         |
 +---------------------------+--------------------------------------------------------------------+
-| Legacy invalid message    | The value {{ value }} is not valid.                                |
-+---------------------------+--------------------------------------------------------------------+
 | Parent type               | :doc:`FormType </reference/forms/types/form>`                      |
 +---------------------------+--------------------------------------------------------------------+
 | Class                     | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\WeekType` |

From e1573270fed16a31515c8b97eb175acc09fbf2c0 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 25 Sep 2024 17:49:56 +0200
Subject: [PATCH 360/747] [Testing] Remove an old article

---
 _build/redirection_map          |  1 +
 testing/http_authentication.rst | 14 --------------
 2 files changed, 1 insertion(+), 14 deletions(-)
 delete mode 100644 testing/http_authentication.rst

diff --git a/_build/redirection_map b/_build/redirection_map
index f7c1f65033a..5c11914cfcb 100644
--- a/_build/redirection_map
+++ b/_build/redirection_map
@@ -568,3 +568,4 @@
 /messenger/multiple_buses /messenger#messenger-multiple-buses
 /frontend/encore/server-data /frontend/server-data
 /components/string /string
+/testing/http_authentication /testing#testing_logging_in_users
diff --git a/testing/http_authentication.rst b/testing/http_authentication.rst
deleted file mode 100644
index 46ddb82b87d..00000000000
--- a/testing/http_authentication.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-How to Simulate HTTP Authentication in a Functional Test
-========================================================
-
-.. caution::
-
-    Starting from Symfony 5.1, a ``loginUser()`` method was introduced to
-    ease testing secured applications. See :ref:`testing_logging_in_users`
-    for more information about this.
-
-    If you are still using an older version of Symfony, view
-    `previous versions of this article`_ for information on how to simulate
-    HTTP authentication.
-
-.. _previous versions of this article: https://symfony.com/doc/5.0/testing/http_authentication.html

From 299e6f5e4a4c7a57683aebf315c99df11214beb6 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 25 Sep 2024 17:59:26 +0200
Subject: [PATCH 361/747] [Doctrine][Security] Remove an old article about
 registration forms

---
 _build/redirection_map         |  1 +
 doctrine.rst                   |  1 -
 doctrine/registration_form.rst | 15 ---------------
 security.rst                   |  2 ++
 4 files changed, 3 insertions(+), 16 deletions(-)
 delete mode 100644 doctrine/registration_form.rst

diff --git a/_build/redirection_map b/_build/redirection_map
index 5c11914cfcb..8f31032e7a5 100644
--- a/_build/redirection_map
+++ b/_build/redirection_map
@@ -569,3 +569,4 @@
 /frontend/encore/server-data /frontend/server-data
 /components/string /string
 /testing/http_authentication /testing#testing_logging_in_users
+/doctrine/registration_form /security#security-make-registration-form
diff --git a/doctrine.rst b/doctrine.rst
index aba27545211..ca1ed25b7b5 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -1103,7 +1103,6 @@ Learn more
 
     doctrine/associations
     doctrine/events
-    doctrine/registration_form
     doctrine/custom_dql_functions
     doctrine/dbal
     doctrine/multiple_entity_managers
diff --git a/doctrine/registration_form.rst b/doctrine/registration_form.rst
deleted file mode 100644
index 7063b7157a4..00000000000
--- a/doctrine/registration_form.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-How to Implement a Registration Form
-====================================
-
-This article has been removed because it only explained things that are
-already explained in other articles. Specifically, to implement a registration
-form you must:
-
-#. :ref:`Define a class to represent users <create-user-class>`;
-#. :doc:`Create a form </forms>` to ask for the registration information (you can
-   generate this with the ``make:registration-form`` command provided by the `MakerBundle`_);
-#. Create :doc:`a controller </controller>` to :ref:`process the form <processing-forms>`;
-#. :ref:`Protect some parts of your application <security-access-control>` so that
-   only registered users can access to them.
-
-.. _`MakerBundle`: https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html
diff --git a/security.rst b/security.rst
index 7b1ba5b0b1d..03f41d1714e 100644
--- a/security.rst
+++ b/security.rst
@@ -449,6 +449,8 @@ the database::
     Doctrine repository class related to the user class must implement the
     :class:`Symfony\\Component\\Security\\Core\\User\\PasswordUpgraderInterface`.
 
+.. _security-make-registration-form:
+
 .. tip::
 
     The ``make:registration-form`` maker command can help you set-up the

From 411cd509e036f8169d8a0975bf246d5de23946ea Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 26 Sep 2024 11:11:38 +0200
Subject: [PATCH 362/747] [Form] Remove a legacy article

---
 _build/redirection_map     |  1 +
 form/form_dependencies.rst | 12 ------------
 forms.rst                  |  1 -
 3 files changed, 1 insertion(+), 13 deletions(-)
 delete mode 100644 form/form_dependencies.rst

diff --git a/_build/redirection_map b/_build/redirection_map
index 8f31032e7a5..dd4c92e0776 100644
--- a/_build/redirection_map
+++ b/_build/redirection_map
@@ -570,3 +570,4 @@
 /components/string /string
 /testing/http_authentication /testing#testing_logging_in_users
 /doctrine/registration_form /security#security-make-registration-form
+/form/form_dependencies /form/create_custom_field_type
diff --git a/form/form_dependencies.rst b/form/form_dependencies.rst
deleted file mode 100644
index 96b067362ff..00000000000
--- a/form/form_dependencies.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-How to Access Services or Config from Inside a Form
-===================================================
-
-The content of this article is no longer relevant because in current Symfony
-versions, form classes are services by default and you can inject services in
-them using the :doc:`service autowiring </service_container/autowiring>` feature.
-
-Read the article about :doc:`creating custom form types </form/create_custom_field_type>`
-to see an example of how to inject the database service into a form type. In the
-same article you can also read about
-:ref:`configuration options for form types <form-type-config-options>`, which is
-another way of passing services to forms.
diff --git a/forms.rst b/forms.rst
index 1e891ab23ef..a90e4ee1772 100644
--- a/forms.rst
+++ b/forms.rst
@@ -964,7 +964,6 @@ Advanced Features:
 
     /controller/upload_file
     /security/csrf
-    /form/form_dependencies
     /form/create_custom_field_type
     /form/data_transformers
     /form/data_mappers

From eacc9c3980b47b93c7889034dc088f2f483314e8 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 25 Sep 2024 19:52:39 +0200
Subject: [PATCH 363/747] [Doctrine] Delete the article about reverse
 engineering

---
 _build/redirection_map           |  1 +
 doctrine.rst                     |  5 ++---
 doctrine/reverse_engineering.rst | 15 ---------------
 3 files changed, 3 insertions(+), 18 deletions(-)
 delete mode 100644 doctrine/reverse_engineering.rst

diff --git a/_build/redirection_map b/_build/redirection_map
index dd4c92e0776..115ec75ade2 100644
--- a/_build/redirection_map
+++ b/_build/redirection_map
@@ -571,3 +571,4 @@
 /testing/http_authentication /testing#testing_logging_in_users
 /doctrine/registration_form /security#security-make-registration-form
 /form/form_dependencies /form/create_custom_field_type
+/doctrine/reverse_engineering /doctrine#doctrine-adding-mapping
diff --git a/doctrine.rst b/doctrine.rst
index ca1ed25b7b5..dc42a5b9e73 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -84,6 +84,8 @@ affect how Doctrine functions.
     There are many other Doctrine commands. Run ``php bin/console list doctrine``
     to see a full list.
 
+.. _doctrine-adding-mapping:
+
 Creating an Entity Class
 ------------------------
 
@@ -91,8 +93,6 @@ Suppose you're building an application where products need to be displayed.
 Without even thinking about Doctrine or databases, you already know that
 you need a ``Product`` object to represent those products.
 
-.. _doctrine-adding-mapping:
-
 You can use the ``make:entity`` command to create this class and any fields you
 need. The command will ask you some questions - answer them like done below:
 
@@ -1107,7 +1107,6 @@ Learn more
     doctrine/dbal
     doctrine/multiple_entity_managers
     doctrine/resolve_target_entity
-    doctrine/reverse_engineering
     testing/database
 
 .. _`Doctrine`: https://www.doctrine-project.org/
diff --git a/doctrine/reverse_engineering.rst b/doctrine/reverse_engineering.rst
deleted file mode 100644
index 35c8e729c2d..00000000000
--- a/doctrine/reverse_engineering.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-How to Generate Entities from an Existing Database
-==================================================
-
-.. caution::
-
-    The ``doctrine:mapping:import`` command used to generate Doctrine entities
-    from existing databases was deprecated by Doctrine in 2019 and there's no
-    replacement for it.
-
-    Instead, you can use the ``make:entity`` command from `Symfony Maker Bundle`_
-    to help you generate the code of your Doctrine entities. This command
-    requires manual supervision because it doesn't generate entities from
-    existing databases.
-
-.. _`Symfony Maker Bundle`: https://symfony.com/bundles/SymfonyMakerBundle/current/index.html

From 2492dd1a3dc9df692c3061009ba9d21bd9ef8b16 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 23 Sep 2024 08:56:16 +0200
Subject: [PATCH 364/747] [Console] Document the silent verbosity level

---
 components/console/usage.rst |  8 ++++++++
 console/input.rst            |  7 ++++++-
 console/verbosity.rst        | 23 ++++++++++++++++++++---
 3 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/components/console/usage.rst b/components/console/usage.rst
index d7725e8926e..591994948b8 100644
--- a/components/console/usage.rst
+++ b/components/console/usage.rst
@@ -65,9 +65,17 @@ You can suppress output with:
 
 .. code-block:: terminal
 
+    # suppresses all output, including errors
+    $ php application.php list --silent
+
+    # suppresses all output except errors
     $ php application.php list --quiet
     $ php application.php list -q
 
+.. versionadded:: 7.2
+
+    The ``--silent`` option was introduced in Symfony 7.2.
+
 You can get more verbose messages (if this is supported for a command)
 with:
 
diff --git a/console/input.rst b/console/input.rst
index 6e7fc85a055..c038ace56fc 100644
--- a/console/input.rst
+++ b/console/input.rst
@@ -446,12 +446,17 @@ The Console component adds some predefined options to all commands:
 
 * ``--verbose``: sets the verbosity level (e.g. ``1`` the default, ``2`` and
   ``3``, or you can use respective shortcuts ``-v``, ``-vv`` and ``-vvv``)
-* ``--quiet``: disables output and interaction
+* ``--silent``: disables all output and interaction, including errors
+* ``--quiet``: disables output and interaction, but errors are still displayed
 * ``--no-interaction``: disables interaction
 * ``--version``: outputs the version number of the console application
 * ``--help``: displays the command help
 * ``--ansi|--no-ansi``: whether to force of disable coloring the output
 
+.. versionadded:: 7.2
+
+    The ``--silent`` option was introduced in Symfony 7.2.
+
 When using the ``FrameworkBundle``, two more options are predefined:
 
 * ``--env``: sets the Kernel configuration environment (defaults to ``APP_ENV``)
diff --git a/console/verbosity.rst b/console/verbosity.rst
index f7a1a1e5e59..9910dca0c3d 100644
--- a/console/verbosity.rst
+++ b/console/verbosity.rst
@@ -7,7 +7,10 @@ messages, but you can control their verbosity with the ``-q`` and ``-v`` options
 
 .. code-block:: terminal
 
-    # do not output any message (not even the command result messages)
+    # suppress all output, including errors
+    $ php bin/console some-command --silent
+
+    # suppress all output (even the command result messages) but display errors
     $ php bin/console some-command -q
     $ php bin/console some-command --quiet
 
@@ -23,6 +26,10 @@ messages, but you can control their verbosity with the ``-q`` and ``-v`` options
     # display all messages (useful to debug errors)
     $ php bin/console some-command -vvv
 
+.. versionadded:: 7.2
+
+    The ``--silent`` option was introduced in Symfony 7.2.
+
 The verbosity level can also be controlled globally for all commands with the
 ``SHELL_VERBOSITY`` environment variable (the ``-q`` and ``-v`` options still
 have more precedence over the value of ``SHELL_VERBOSITY``):
@@ -30,6 +37,7 @@ have more precedence over the value of ``SHELL_VERBOSITY``):
 =====================  =========================  ===========================================
 Console option         ``SHELL_VERBOSITY`` value  Equivalent PHP constant
 =====================  =========================  ===========================================
+``--silent``           ``-2``                     ``OutputInterface::VERBOSITY_SILENT``
 ``-q`` or ``--quiet``  ``-1``                     ``OutputInterface::VERBOSITY_QUIET``
 (none)                 ``0``                      ``OutputInterface::VERBOSITY_NORMAL``
 ``-v``                 ``1``                      ``OutputInterface::VERBOSITY_VERBOSE``
@@ -58,7 +66,7 @@ level. For example::
                 'Password: '.$input->getArgument('password'),
             ]);
 
-            // available methods: ->isQuiet(), ->isVerbose(), ->isVeryVerbose(), ->isDebug()
+            // available methods: ->isSilent(), ->isQuiet(), ->isVerbose(), ->isVeryVerbose(), ->isDebug()
             if ($output->isVerbose()) {
                 $output->writeln('User class: '.get_class($user));
             }
@@ -73,10 +81,19 @@ level. For example::
         }
     }
 
-When the quiet level is used, all output is suppressed as the default
+.. versionadded:: 7.2
+
+    The ``isSilent()`` method was introduced in Symfony 7.2.
+
+When the silent or quiet level are used, all output is suppressed as the default
 :method:`Symfony\\Component\\Console\\Output\\Output::write` method returns
 without actually printing.
 
+.. tip::
+
+    When using the ``silent`` verbosity, errors won't be displayed in the console
+    but they will still be logged through the :doc:`Symfony logger </logging>` integration.
+
 .. tip::
 
     The MonologBridge provides a :class:`Symfony\\Bridge\\Monolog\\Handler\\ConsoleHandler`

From ecb343bf576206de34d57a190447b1128684d8cf Mon Sep 17 00:00:00 2001
From: Kevin Bond <kevinbond@gmail.com>
Date: Fri, 27 Sep 2024 13:05:03 +0200
Subject: [PATCH 365/747] [Webhook] add Mailtrap webhook docs

---
 webhook.rst | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/webhook.rst b/webhook.rst
index 176abc49cd2..e2c7083ac43 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -28,6 +28,7 @@ MailerSend     ``mailer.webhook.request_parser.mailersend``
 Mailgun        ``mailer.webhook.request_parser.mailgun``
 Mailjet        ``mailer.webhook.request_parser.mailjet``
 Mailomat       ``mailer.webhook.request_parser.mailomat``
+Mailtrap       ``mailer.webhook.request_parser.mailtrap``
 Postmark       ``mailer.webhook.request_parser.postmark``
 Resend         ``mailer.webhook.request_parser.resend``
 Sendgrid       ``mailer.webhook.request_parser.sendgrid``
@@ -40,7 +41,8 @@ Sweego         ``mailer.webhook.request_parser.sweego``
 
 .. versionadded:: 7.2
 
-    The ``Mailomat`` and ``Sweego`` integrations were introduced in Symfony 7.2.
+    The ``Mailomat``, ``Mailtrap``, and ``Sweego`` integrations were introduced in
+    Symfony 7.2.
 
 .. note::
 

From 0bb5a68545d695d7bf9f9ec31843920756ffdf44 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 30 Sep 2024 09:51:52 +0200
Subject: [PATCH 366/747] [String] Add the `AbstractString::kebab()` method

---
 string.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/string.rst b/string.rst
index f2856976986..d9fdeded470 100644
--- a/string.rst
+++ b/string.rst
@@ -232,6 +232,8 @@ Methods to Change Case
     u('Foo: Bar-baz.')->camel(); // 'fooBarBaz'
     // changes all graphemes/code points to snake_case
     u('Foo: Bar-baz.')->snake(); // 'foo_bar_baz'
+    // changes all graphemes/code points to kebab-case
+    u('Foo: Bar-baz.')->kebab(); // 'foo-bar-baz'
     // other cases can be achieved by chaining methods. E.g. PascalCase:
     u('Foo: Bar-baz.')->camel()->title(); // 'FooBarBaz'
 
@@ -240,6 +242,10 @@ Methods to Change Case
     The ``localeLower()``, ``localeUpper()`` and ``localeTitle()`` methods were
     introduced in Symfony 7.1.
 
+.. versionadded:: 7.2
+
+    The ``kebab()`` method was introduced in Symfony 7.2.
+
 The methods of all string classes are case-sensitive by default. You can perform
 case-insensitive operations with the ``ignoreCase()`` method::
 

From d810f6caabcc1960f5e3d7ffde08a44fa2733fb1 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 30 Sep 2024 10:09:10 +0200
Subject: [PATCH 367/747] Minor tweaks

---
 configuration.rst | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/configuration.rst b/configuration.rst
index 52dc9b98c95..5ebe952740e 100644
--- a/configuration.rst
+++ b/configuration.rst
@@ -385,22 +385,17 @@ a new ``locale`` parameter is added to the ``config/services.yaml`` file).
 Configuration parameters are usually validation-free, but you can ensure that
 essential parameters for your application's functionality are not empty::
 
-    // ContainerBuilder
-    $container->parameterCannotBeEmpty('app.private_key', 'Did you forget to configure a non-empty value for "app.private_key" parameter?');
+    /** @var ContainerBuilder $container */
+    $container->parameterCannotBeEmpty('app.private_key', 'Did you forget to set a value for the "app.private_key" parameter?');
 
 If a non-empty parameter is ``null``, an empty string ``''``, or an empty array ``[]``,
-Symfony will throw an exception with the custom error message when attempting to
-retrieve the value of this parameter.
+Symfony will throw an exception. This validation is **not** made at compile time
+but when attempting to retrieve the value of the parameter.
 
 .. versionadded:: 7.2
 
     Validating non-empty parameters was introduced in Symfony 7.2.
 
-.. note::
-
-    Please note that this validation will *only* occur if a non-empty parameter value
-    is retrieved; otherwise, no exception will be thrown.
-
 .. seealso::
 
     Later in this article you can read how to

From a3815364478bdf7d2569655a1092880f06bfc94d Mon Sep 17 00:00:00 2001
From: Pierre Rineau <pierre.rineau@makina-corpus.com>
Date: Fri, 28 Jun 2024 12:34:40 +0200
Subject: [PATCH 368/747] [Messenger] document the #[AsMessage] attribute

---
 messenger.rst            | 49 ++++++++++++++++++++++++++++++++++++++++
 reference/attributes.rst |  1 +
 2 files changed, 50 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index cecb84d9dec..8ba335b4e2b 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -345,6 +345,55 @@ to multiple transports:
     name as its only argument. For more information about stamps, see
     `Envelopes & Stamps`_.
 
+.. _messenger-message-attribute:
+
+Configuring Routing Using Attributes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can optionally use the `#[AsMessage]` attribute to configure message transport::
+
+    // src/Message/SmsNotification.php
+    namespace App\Message;
+
+    use Symfony\Component\Messenger\Attribute\AsMessage;
+
+    #[AsMessage(transport: 'async')]
+    class SmsNotification
+    {
+        public function __construct(
+            private string $content,
+        ) {
+        }
+
+        public function getContent(): string
+        {
+            return $this->content;
+        }
+    }
+
+.. note::
+
+    If you configure routing with both configuration and attributes, the
+    configuration will take precedence over the attributes and override
+    them. This allows to override routing on a per-environment basis
+    for example:
+
+    .. code-block:: yaml
+
+        # config/packages/messenger.yaml
+        when@dev:
+            framework:
+                messenger:
+                    routing:
+                        # override class attribute
+                        'App\Message\SmsNotification': sync
+
+.. tip::
+
+    The `$transport` parameter can be either a `string` or an `array`: configuring multiple
+    transports is possible. You may also repeat the attribute if you prefer instead of using
+    an array.
+
 Doctrine Entities in Messages
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/reference/attributes.rst b/reference/attributes.rst
index 559893ca2e4..19a27b71793 100644
--- a/reference/attributes.rst
+++ b/reference/attributes.rst
@@ -79,6 +79,7 @@ HttpKernel
 Messenger
 ~~~~~~~~~
 
+* :ref:`AsMessage <messenger-message-attribute>`
 * :ref:`AsMessageHandler <messenger-handler>`
 
 RemoteEvent

From a8a0e2beed33617c7143fbbeaabee884f3b9f357 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 30 Sep 2024 10:25:40 +0200
Subject: [PATCH 369/747] [AssetMapper] Document the filtering options of
 debug:asset-map

---
 frontend/asset_mapper.rst | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index f6300e7adb9..6987718381f 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -137,6 +137,28 @@ This will show you all the mapped paths and the assets inside of each:
 The "Logical Path" is the path to use when referencing the asset, like
 from a template.
 
+The ``debug:asset-map`` command provides several options to filter results:
+
+.. code-block:: terminal
+
+    # provide an asset name or dir to only show results that match it
+    $ php bin/console debug:asset-map bootstrap.js
+    $ php bin/console debug:asset-map style/
+
+    # provide an extension to only show that file type
+    $ php bin/console debug:asset-map --ext=css
+
+    # you can also only show assets in vendor/ dir or exclude any results from it
+    $ php bin/console debug:asset-map --vendor
+    $ php bin/console debug:asset-map --no-vendor
+
+    # you can also combine all filters (e.g. find bold web fonts in your own asset dirs)
+    $ php bin/console debug:asset-map bold --no-vendor --ext=woff2
+
+.. versionadded:: 7.2
+
+    The options to filter ``debug:asset-map`` results were introduced in Symfony 7.2.
+
 .. _importmaps-javascript:
 
 Importmaps & Writing JavaScript

From 476c1c1e6795e3384f6d392036147727af627528 Mon Sep 17 00:00:00 2001
From: Kevin Bond <kevinbond@gmail.com>
Date: Tue, 1 Oct 2024 04:12:12 -0400
Subject: [PATCH 370/747] [Mailer] mark Mailtrap as having Webhook support

---
 mailer.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mailer.rst b/mailer.rst
index a8d0eda3072..2954fa7217a 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -109,7 +109,7 @@ Service               Install with                                    Webhook su
 `Mailomat`_           ``composer require symfony/mailomat-mailer``    yes
 `MailPace`_           ``composer require symfony/mail-pace-mailer``
 `MailerSend`_         ``composer require symfony/mailer-send-mailer``
-`Mailtrap`_           ``composer require symfony/mailtrap-mailer``
+`Mailtrap`_           ``composer require symfony/mailtrap-mailer``    yes
 `Mandrill`_           ``composer require symfony/mailchimp-mailer``
 `Postal`_             ``composer require symfony/postal-mailer``
 `Postmark`_           ``composer require symfony/postmark-mailer``    yes

From 9ac77eefb559c3e223722db352b485c374df9f98 Mon Sep 17 00:00:00 2001
From: W0rma <beck.worma@gmail.com>
Date: Tue, 1 Oct 2024 13:12:01 +0200
Subject: [PATCH 371/747] [Validator] Add example for passing groups and
 payload to the Compound constraint

---
 reference/constraints/Compound.rst | 44 ++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/reference/constraints/Compound.rst b/reference/constraints/Compound.rst
index fc8081f5917..0d0dc933ae0 100644
--- a/reference/constraints/Compound.rst
+++ b/reference/constraints/Compound.rst
@@ -102,6 +102,50 @@ You can now use it anywhere you need it:
             }
         }
 
+Validation groups and payload can be passed via constructor:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Entity/User.php
+        namespace App\Entity\User;
+
+        use App\Validator\Constraints as Assert;
+
+        class User
+        {
+            #[Assert\PasswordRequirements(
+                groups: ['registration'],
+                payload: ['severity' => 'error'],
+            )]
+            public string $plainPassword;
+        }
+
+    .. code-block:: php
+
+        // src/Entity/User.php
+        namespace App\Entity\User;
+
+        use App\Validator\Constraints as Assert;
+        use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+        class User
+        {
+            public static function loadValidatorMetadata(ClassMetadata $metadata): void
+            {
+                $metadata->addPropertyConstraint('plainPassword', new Assert\PasswordRequirements(
+                    groups: ['registration'],
+                    payload: ['severity' => 'error'],
+                ));
+            }
+        }
+
+.. versionadded:: 7.2
+
+    Support for passing validation groups and the payload to the constructor
+    of the ``Compound`` class was introduced in Symfony 7.2.
+
 Options
 -------
 

From 743f4c6096f7d6fdd9fc968e402c486064a3b9a6 Mon Sep 17 00:00:00 2001
From: Pierre Ambroise <pierre27.ambroise@gmail.com>
Date: Tue, 1 Oct 2024 14:45:15 +0200
Subject: [PATCH 372/747] Document logical xor in expression language

---
 reference/formats/expression_language.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/reference/formats/expression_language.rst b/reference/formats/expression_language.rst
index f902087d380..368c95bc2a8 100644
--- a/reference/formats/expression_language.rst
+++ b/reference/formats/expression_language.rst
@@ -345,6 +345,11 @@ Logical Operators
 * ``not`` or ``!``
 * ``and`` or ``&&``
 * ``or`` or ``||``
+* ``xor``
+
+.. versionadded:: 7.2
+
+    Support for the ``xor`` logical operator was introduced in Symfony 7.2.
 
 For example::
 
@@ -487,6 +492,8 @@ The following table summarizes the operators and their associativity from the
 +-----------------------------------------------------------------+---------------+
 | ``and``, ``&&``                                                 | left          |
 +-----------------------------------------------------------------+---------------+
+| ``xor``                                                         | left          |
++-----------------------------------------------------------------+---------------+
 | ``or``, ``||``                                                  | left          |
 +-----------------------------------------------------------------+---------------+
 

From e8084a2413e3675713321e3749fe9bbbc37eea79 Mon Sep 17 00:00:00 2001
From: johan Vlaar <johan@adivare.nl>
Date: Tue, 1 Oct 2024 16:10:51 +0200
Subject: [PATCH 373/747] [Mailer][Webhook] Mandrill Webhook support

---
 mailer.rst  | 2 +-
 webhook.rst | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index 2954fa7217a..3dbf8a79575 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -110,7 +110,7 @@ Service               Install with                                    Webhook su
 `MailPace`_           ``composer require symfony/mail-pace-mailer``
 `MailerSend`_         ``composer require symfony/mailer-send-mailer``
 `Mailtrap`_           ``composer require symfony/mailtrap-mailer``    yes
-`Mandrill`_           ``composer require symfony/mailchimp-mailer``
+`Mandrill`_           ``composer require symfony/mailchimp-mailer``   yes
 `Postal`_             ``composer require symfony/postal-mailer``
 `Postmark`_           ``composer require symfony/postmark-mailer``    yes
 `Resend`_             ``composer require symfony/resend-mailer``      yes
diff --git a/webhook.rst b/webhook.rst
index e2c7083ac43..6b79da037e4 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -24,6 +24,7 @@ Currently, the following third-party mailer providers support webhooks:
 Mailer Service Parser service name
 ============== ============================================
 Brevo          ``mailer.webhook.request_parser.brevo``
+Mandrill       ``mailer.webhook.request_parser.mailchimp``
 MailerSend     ``mailer.webhook.request_parser.mailersend``
 Mailgun        ``mailer.webhook.request_parser.mailgun``
 Mailjet        ``mailer.webhook.request_parser.mailjet``
@@ -41,7 +42,7 @@ Sweego         ``mailer.webhook.request_parser.sweego``
 
 .. versionadded:: 7.2
 
-    The ``Mailomat``, ``Mailtrap``, and ``Sweego`` integrations were introduced in
+    The ``Mandrill``,  ``Mailomat``, ``Mailtrap``, and ``Sweego`` integrations were introduced in
     Symfony 7.2.
 
 .. note::

From 6e2045a3ed2689f9443eb062ea15a54b7261e781 Mon Sep 17 00:00:00 2001
From: W0rma <beck.worma@gmail.com>
Date: Wed, 2 Oct 2024 07:21:30 +0200
Subject: [PATCH 374/747] [Messenger] Describe the options of the
 messenger:failed:retry command

---
 messenger.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index cecb84d9dec..9f75ce33bed 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1173,6 +1173,8 @@ to retry them:
     $ php bin/console messenger:failed:show 20 -vv
 
     # view and retry messages one-by-one
+    # for each message the command asks whether the message should be retried,
+    # skipped or deleted
     $ php bin/console messenger:failed:retry -vv
 
     # retry specific messages
@@ -1191,6 +1193,11 @@ If the message fails again, it will be re-sent back to the failure transport
 due to the normal :ref:`retry rules <messenger-retries-failures>`. Once the max
 retry has been hit, the message will be discarded permanently.
 
+.. versionadded:: 7.2
+
+    The possibility to skip a message in the `messenger:failed:retry`
+    command was introduced in Symfony 7.2
+
 Multiple Failed Transports
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From 795148ee5958773c4f7be614f56358663a677380 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 2 Oct 2024 17:46:12 +0200
Subject: [PATCH 375/747] Minor tweaks

---
 messenger.rst | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index 9f75ce33bed..add197e8df6 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1172,9 +1172,7 @@ to retry them:
     # see details about a specific failure
     $ php bin/console messenger:failed:show 20 -vv
 
-    # view and retry messages one-by-one
-    # for each message the command asks whether the message should be retried,
-    # skipped or deleted
+    # for each message, this command asks whether to retry, skip, or delete
     $ php bin/console messenger:failed:retry -vv
 
     # retry specific messages
@@ -1195,8 +1193,8 @@ retry has been hit, the message will be discarded permanently.
 
 .. versionadded:: 7.2
 
-    The possibility to skip a message in the `messenger:failed:retry`
-    command was introduced in Symfony 7.2
+    The option to skip a message in the ``messenger:failed:retry`` command was
+    introduced in Symfony 7.2
 
 Multiple Failed Transports
 ~~~~~~~~~~~~~~~~~~~~~~~~~~

From 50ab3eed6e865d381b3ef914529a63f0a9bb5395 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 7 Oct 2024 08:37:24 +0200
Subject: [PATCH 376/747] [Mailer] Support unicode email addresses

---
 mailer.rst | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/mailer.rst b/mailer.rst
index 2954fa7217a..e21951df557 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -542,6 +542,10 @@ both strings or address objects::
         // email address as a simple string
         ->from('fabien@example.com')
 
+        // non-ASCII characters are supported both in the local part and the domain;
+        // if the SMTP server doesn't support this feature, you'll see an exception
+        ->from('jânë.dœ@ëxãmplę.com')
+
         // email address as an object
         ->from(new Address('fabien@example.com'))
 
@@ -556,6 +560,11 @@ both strings or address objects::
         // ...
     ;
 
+.. versionadded:: 7.2
+
+    Support for non-ASCII email addresses (e.g. ``jânë.dœ@ëxãmplę.com``)
+    was introduced in Symfony 7.2.
+
 .. tip::
 
     Instead of calling ``->from()`` *every* time you create a new email, you can

From 861a0968eec52f837115b5667a18df6485bd2ced Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jib=C3=A9=20Barth?= <barth.jib@gmail.com>
Date: Sun, 6 Oct 2024 19:28:44 +0200
Subject: [PATCH 377/747] [Console] Document FinishedIndicator for Progress
 indicator

---
 .../console/helpers/progressindicator.rst     | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/components/console/helpers/progressindicator.rst b/components/console/helpers/progressindicator.rst
index d64ec6367b7..dd18c6bdbc9 100644
--- a/components/console/helpers/progressindicator.rst
+++ b/components/console/helpers/progressindicator.rst
@@ -95,6 +95,26 @@ The progress indicator will now look like this:
      ⠹ Processing...
      ⢸ Processing...
 
+Custom Finished Indicator
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Once the progress indicator is finished, it keeps by default the latest indicator value. You can replace it with a your own::
+
+    $progressIndicator->finish('Finished', '✅');
+
+Then the progress indicator will render like this:
+
+.. code-block:: text
+
+     ⠏ Processing...
+     ⠛ Processing...
+     ✅ Finished
+
+.. versionadded:: 7.2
+
+    The ``finishedIndicator`` parameter for method ``finish()`` was introduced in Symfony 7.2.
+
+
 Customize Placeholders
 ~~~~~~~~~~~~~~~~~~~~~~
 

From 1b26f7681a2f4aff35adf89014767972a50a8585 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 7 Oct 2024 10:21:40 +0200
Subject: [PATCH 378/747] Minor tweaks

---
 components/console/helpers/progressindicator.rst | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/components/console/helpers/progressindicator.rst b/components/console/helpers/progressindicator.rst
index dd18c6bdbc9..fedc8439e64 100644
--- a/components/console/helpers/progressindicator.rst
+++ b/components/console/helpers/progressindicator.rst
@@ -95,10 +95,8 @@ The progress indicator will now look like this:
      ⠹ Processing...
      ⢸ Processing...
 
-Custom Finished Indicator
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Once the progress indicator is finished, it keeps by default the latest indicator value. You can replace it with a your own::
+Once the progress indicator is finished, it keeps the latest indicator value by
+default. You can replace it with your own::
 
     $progressIndicator->finish('Finished', '✅');
 
@@ -114,7 +112,6 @@ Then the progress indicator will render like this:
 
     The ``finishedIndicator`` parameter for method ``finish()`` was introduced in Symfony 7.2.
 
-
 Customize Placeholders
 ~~~~~~~~~~~~~~~~~~~~~~
 

From 2c93089f1781396bcd54b6f7f8eec403fa1c87a8 Mon Sep 17 00:00:00 2001
From: Maxime Doutreluingne <maxime.doutreluingne@gmail.com>
Date: Sat, 28 Sep 2024 18:47:17 +0200
Subject: [PATCH 379/747] [Serializer] Deprecate
 ``AdvancedNameConverterInterface``

---
 components/serializer.rst | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/components/serializer.rst b/components/serializer.rst
index de8f67c853d..0764612e28a 100644
--- a/components/serializer.rst
+++ b/components/serializer.rst
@@ -549,12 +549,12 @@ A custom name converter can handle such cases::
 
     class OrgPrefixNameConverter implements NameConverterInterface
     {
-        public function normalize(string $propertyName): string
+        public function normalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
         {
             return 'org_'.$propertyName;
         }
 
-        public function denormalize(string $propertyName): string
+        public function denormalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
         {
             // removes 'org_' prefix
             return str_starts_with($propertyName, 'org_') ? substr($propertyName, 4) : $propertyName;
@@ -584,12 +584,6 @@ and :class:`Symfony\\Component\\Serializer\\Normalizer\\PropertyNormalizer`::
     $companyCopy = $serializer->deserialize($json, Company::class, 'json');
     // Same data as $company
 
-.. note::
-
-    You can also implement
-    :class:`Symfony\\Component\\Serializer\\NameConverter\\AdvancedNameConverterInterface`
-    to access the current class name, format and context.
-
 .. _using-camelized-method-names-for-underscored-attributes:
 
 CamelCase to snake_case

From e14e05f4eaea753f625656949d9d9fc4814510ff Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 3 Oct 2024 10:13:16 +0200
Subject: [PATCH 380/747] Document the new `SYMFONY_*` env vars

---
 deployment/proxies.rst                | 11 ++++++++++-
 reference/configuration/framework.rst | 14 ++++++++++++--
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/deployment/proxies.rst b/deployment/proxies.rst
index fc6f855451d..cd5649d979a 100644
--- a/deployment/proxies.rst
+++ b/deployment/proxies.rst
@@ -22,7 +22,11 @@ Solution: ``setTrustedProxies()``
 ---------------------------------
 
 To fix this, you need to tell Symfony which reverse proxy IP addresses to trust
-and what headers your reverse proxy uses to send information:
+and what headers your reverse proxy uses to send information.
+
+You can do that by setting the ``SYMFONY_TRUSTED_PROXIES`` and ``SYMFONY_TRUSTED_HEADERS``
+environment variables on your machine. Alternatively, you can configure them
+using the following configuration options:
 
 .. configuration-block::
 
@@ -93,6 +97,11 @@ and what headers your reverse proxy uses to send information:
     ``private_ranges`` as a shortcut for private IP address ranges for the
     ``trusted_proxies`` option was introduced in Symfony 7.1.
 
+.. versionadded:: 7.2
+
+    Support for the ``SYMFONY_TRUSTED_PROXIES`` and ``SYMFONY_TRUSTED_HEADERS``
+    environment variables was introduced in Symfony 7.2.
+
 .. caution::
 
     Enabling the ``Request::HEADER_X_FORWARDED_HOST`` option exposes the
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 19f72bb6cb3..53edf220642 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -198,7 +198,12 @@ named ``kernel.http_method_override``.
 trust_x_sendfile_type_header
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-**type**: ``boolean`` **default**: ``false``
+**type**: ``boolean`` **default**: ``%env(bool:default::SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER)%``
+
+.. versionadded:: 7.2
+
+    In Symfony 7.2, the default value of this option was changed from ``false`` to the
+    value stored in the ``SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER`` environment variable.
 
 ``X-Sendfile`` is a special HTTP header that tells web servers to replace the
 response contents by the file that is defined in that header. This improves
@@ -450,7 +455,12 @@ in debug mode.
 trusted_hosts
 ~~~~~~~~~~~~~
 
-**type**: ``array`` | ``string`` **default**: ``[]``
+**type**: ``array`` | ``string`` **default**: ``['%env(default::SYMFONY_TRUSTED_HOSTS)%']``
+
+.. versionadded:: 7.2
+
+    In Symfony 7.2, the default value of this option was changed from ``[]`` to the
+    value stored in the ``SYMFONY_TRUSTED_HOSTS`` environment variable.
 
 A lot of different attacks have been discovered relying on inconsistencies
 in handling the ``Host`` header by various software (web servers, reverse

From 03922de2588b2ec965cd31f40c2ecc4d9b3e0c97 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 3 Oct 2024 16:04:31 +0200
Subject: [PATCH 381/747] [Ldap] Add support for `sasl_bind` and `whoami` LDAP
 operations

---
 components/ldap.rst | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/components/ldap.rst b/components/ldap.rst
index 89094fad0b7..d5f6bc3fdfe 100644
--- a/components/ldap.rst
+++ b/components/ldap.rst
@@ -74,6 +74,19 @@ distinguished name (DN) and the password of a user::
 
     When the LDAP server allows unauthenticated binds, a blank password will always be valid.
 
+You can also use the :method:`Symfony\\Component\\Ldap\\Ldap::saslBind` method
+for binding to an LDAP server using `SASL`_::
+
+    // this method defines other optional arguments like $mech, $realm, $authcId, etc.
+    $ldap->saslBind($dn, $password);
+
+After binding to the LDAP server, you can use the :method:`Symfony\\Component\\Ldap\\Ldap::whoami`
+method to get the distinguished name (DN) of the authenticated and authorized user.
+
+.. versionadded:: 7.2
+
+    The ``saslBind()`` and ``whoami()`` methods were introduced in Symfony 7.2.
+
 Once bound (or if you enabled anonymous authentication on your
 LDAP server), you may query the LDAP server using the
 :method:`Symfony\\Component\\Ldap\\Ldap::query` method::
@@ -183,3 +196,5 @@ Possible operation types are ``LDAP_MODIFY_BATCH_ADD``, ``LDAP_MODIFY_BATCH_REMO
 ``LDAP_MODIFY_BATCH_REMOVE_ALL``, ``LDAP_MODIFY_BATCH_REPLACE``. Parameter
 ``$values`` must be ``NULL`` when using ``LDAP_MODIFY_BATCH_REMOVE_ALL``
 operation type.
+
+.. _`SASL`: https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer

From 3df38498bba9aaede83aafad5366d6449630d437 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=F0=9F=A6=85KoNekoD?= <moskva111@yahoo.com>
Date: Thu, 10 Oct 2024 11:01:05 +0300
Subject: [PATCH 382/747] feat(when constraint): add context variable

---
 reference/constraints/When.rst | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/reference/constraints/When.rst b/reference/constraints/When.rst
index e1e8ac895ce..12b43fc7d63 100644
--- a/reference/constraints/When.rst
+++ b/reference/constraints/When.rst
@@ -163,7 +163,7 @@ validation of constraints won't be triggered.
 To learn more about the expression language syntax, see
 :doc:`/reference/formats/expression_language`.
 
-Depending on how you use the constraint, you have access to 1 or 2 variables
+Depending on how you use the constraint, you have access to 1 or 3 variables
 in your expression:
 
 ``this``
@@ -171,6 +171,8 @@ in your expression:
 ``value``
     The value of the property being validated (only available when
     the constraint is applied to a property).
+``context``
+    This is the context that is used in validation
 
 The ``value`` variable can be used when you want to execute more complex
 validation based on its value:

From 5e8fb6ebd991577c9645d1df13bdabca8cf3b922 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Thu, 10 Oct 2024 14:21:34 +0200
Subject: [PATCH 383/747] [Lock] Add NullStore

---
 components/lock.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/components/lock.rst b/components/lock.rst
index 5a76223112b..69e51a1407b 100644
--- a/components/lock.rst
+++ b/components/lock.rst
@@ -406,6 +406,14 @@ Store                                                       Scope   Blocking  Ex
     A special ``InMemoryStore`` is available for saving locks in memory during
     a process, and can be useful for testing.
 
+.. tip::
+
+    A special ``NullStore`` is available and persist nothing, it can be useful for testing.
+
+.. versionadded:: 7.2
+
+    The :class:`Symfony\\Component\\Lock\\Store\\NullStore` was introduced in Symfony 7.2.
+
 .. _lock-store-flock:
 
 FlockStore

From 52d4f7bc5681bbf563eff8c4db8c439e0151d279 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 10 Oct 2024 16:06:12 +0200
Subject: [PATCH 384/747] Minor reword

---
 components/lock.rst | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/components/lock.rst b/components/lock.rst
index 69e51a1407b..bf75fb49f7a 100644
--- a/components/lock.rst
+++ b/components/lock.rst
@@ -403,12 +403,9 @@ Store                                                       Scope   Blocking  Ex
 
 .. tip::
 
-    A special ``InMemoryStore`` is available for saving locks in memory during
-    a process, and can be useful for testing.
-
-.. tip::
-
-    A special ``NullStore`` is available and persist nothing, it can be useful for testing.
+    Symfony includes two other special stores that are mostly useful for testing:
+    ``InMemoryStore``, which saves locks in memory during a process, and ``NullStore``,
+    which doesn't persist anything.
 
 .. versionadded:: 7.2
 

From 16bccc3a3bab72597e7ad7bf23a291a12f4b958e Mon Sep 17 00:00:00 2001
From: Benjamin Georgeault <bgeorgeault@wedgesama.fr>
Date: Mon, 14 Oct 2024 11:27:37 +0200
Subject: [PATCH 385/747] Add missing ref in constraint map to the new Yaml
 constraint.

---
 reference/constraints/map.rst.inc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/reference/constraints/map.rst.inc b/reference/constraints/map.rst.inc
index e0dbd6c4512..97c049dae90 100644
--- a/reference/constraints/map.rst.inc
+++ b/reference/constraints/map.rst.inc
@@ -34,6 +34,7 @@ String Constraints
 * :doc:`Charset </reference/constraints/Charset>`
 * :doc:`MacAddress </reference/constraints/MacAddress>`
 * :doc:`WordCount </reference/constraints/WordCount>`
+* :doc:`Yaml </reference/constraints/Yaml>`
 
 Comparison Constraints
 ~~~~~~~~~~~~~~~~~~~~~~

From d10abd7ad04171dd74b8032826bdb1db910894c7 Mon Sep 17 00:00:00 2001
From: pan93412 <pan93412@gmail.com>
Date: Fri, 11 Oct 2024 14:19:45 +0800
Subject: [PATCH 386/747] [Notifier] Add LINE Bot notifier

---
 notifier.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/notifier.rst b/notifier.rst
index 8b684ef2d1d..e5671eea534 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -341,6 +341,7 @@ Service                                  Package                               D
 `Firebase`_                              ``symfony/firebase-notifier``         ``firebase://USERNAME:PASSWORD@default``
 `Gitter`_                                ``symfony/gitter-notifier``           ``gitter://TOKEN@default?room_id=ROOM_ID``
 `GoogleChat`_                            ``symfony/google-chat-notifier``      ``googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?thread_key=THREAD_KEY``
+`LINE Bot`_                              ``symfony/line-bot-notifier``         ``linebot://TOKEN@default?receiver=RECEIVER``
 `LINE Notify`_                           ``symfony/line-notify-notifier``      ``linenotify://TOKEN@default``
 `LinkedIn`_                              ``symfony/linked-in-notifier``        ``linkedin://TOKEN:USER_ID@default``
 `Mastodon`_                              ``symfony/mastodon-notifier``         ``mastodon://ACCESS_TOKEN@HOST``
@@ -355,6 +356,10 @@ Service                                  Package                               D
 `Zulip`_                                 ``symfony/zulip-notifier``            ``zulip://EMAIL:TOKEN@HOST?channel=CHANNEL``
 ======================================   ====================================  =============================================================================
 
+.. versionadded:: 7.2
+
+    The ``LINE Bot`` integration was introduced in Symfony 7.2.
+
 .. versionadded:: 7.1
 
     The ``Bluesky`` integration was introduced in Symfony 7.1.
@@ -1100,6 +1105,7 @@ is dispatched. Listeners receive a
 .. _`Iqsms`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Iqsms/README.md
 .. _`iSendPro`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Isendpro/README.md
 .. _`KazInfoTeh`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/KazInfoTeh/README.md
+.. _`LINE Bot`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/LineBot/README.md
 .. _`LINE Notify`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/LineNotify/README.md
 .. _`LightSms`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/LightSms/README.md
 .. _`LinkedIn`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/LinkedIn/README.md

From b4b0c4c727ae35e16807717307ba37ad48b31777 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 14 Oct 2024 11:43:52 +0200
Subject: [PATCH 387/747] Minor tweak

---
 notifier.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/notifier.rst b/notifier.rst
index 7d4ce6ef6be..71af2ccb440 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -370,14 +370,14 @@ Service                                  Package                               D
 `Zulip`_                                 ``symfony/zulip-notifier``            ``zulip://EMAIL:TOKEN@HOST?channel=CHANNEL``
 ======================================   ====================================  =============================================================================
 
-.. versionadded:: 7.2
-
-    The ``LINE Bot`` integration was introduced in Symfony 7.2.
-
 .. versionadded:: 7.1
 
     The ``Bluesky`` integration was introduced in Symfony 7.1.
 
+.. versionadded:: 7.2
+
+    The ``LINE Bot`` integration was introduced in Symfony 7.2.
+
 .. deprecated:: 7.2
 
     The ``Gitter`` integration was removed in Symfony 7.2 because that service

From e55e7cda09565450489232ab9144b752f8fe7e73 Mon Sep 17 00:00:00 2001
From: Yonel Ceruto <yonel.ceruto@scnd.com>
Date: Sun, 13 Oct 2024 15:23:24 -0400
Subject: [PATCH 388/747] documenting choice_lazy option

---
 reference/forms/types/choice.rst              |  2 ++
 .../forms/types/options/choice_lazy.rst.inc   | 31 +++++++++++++++++++
 2 files changed, 33 insertions(+)
 create mode 100644 reference/forms/types/options/choice_lazy.rst.inc

diff --git a/reference/forms/types/choice.rst b/reference/forms/types/choice.rst
index 55f2d016001..2d31aac890c 100644
--- a/reference/forms/types/choice.rst
+++ b/reference/forms/types/choice.rst
@@ -178,6 +178,8 @@ correct types will be assigned to the model.
 
 .. include:: /reference/forms/types/options/choice_loader.rst.inc
 
+.. include:: /reference/forms/types/options/choice_lazy.rst.inc
+
 .. include:: /reference/forms/types/options/choice_name.rst.inc
 
 .. include:: /reference/forms/types/options/choice_translation_domain_enabled.rst.inc
diff --git a/reference/forms/types/options/choice_lazy.rst.inc b/reference/forms/types/options/choice_lazy.rst.inc
new file mode 100644
index 00000000000..db8591a613d
--- /dev/null
+++ b/reference/forms/types/options/choice_lazy.rst.inc
@@ -0,0 +1,31 @@
+``choice_lazy``
+~~~~~~~~~~~~~~~
+
+**type**: ``boolean`` **default**: ``false``
+
+The ``choice_lazy`` option is especially useful when dealing with a large set of
+choices, where loading all of them at once could lead to performance issues or
+significant delays::
+
+    use App\Entity\User;
+    use Symfony\Bridge\Doctrine\Form\Type\EntityType;
+
+    $builder->add('user', EntityType::class, [
+        'class' => User::class,
+        'choice_lazy' => true,
+    ]);
+
+When set to ``true``, and used in combination with the ``choice_loader`` option,
+the form will only load and render the choices that are preset as default values
+or submitted. This allows you to defer loading the full list of choices and can
+improve the performance of your form.
+
+.. caution::
+
+    Please note that when using ``choice_lazy``, you are responsible for providing
+    the user interface to select choices, typically through a JavaScript plugin that
+    can handle the dynamic loading of choices.
+
+.. versionadded:: 7.2
+
+    The ``choice_lazy`` option was introduced in Symfony 7.2.

From e9bd37b9073074b82a31789851c97b6219e79d1e Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Mon, 14 Oct 2024 14:58:35 +0200
Subject: [PATCH 389/747] merge versionadded directives

---
 notifier.rst | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/notifier.rst b/notifier.rst
index 71af2ccb440..b2329b2b28a 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -207,10 +207,6 @@ Service
                     **Webhook support**: No
 ==================  ====================================================================================================================================
 
-.. versionadded:: 7.2
-
-    The ``Primotexto`` integration was introduced in Symfony 7.2.
-
 .. tip::
 
     Use :doc:`Symfony configuration secrets </configuration/secrets>` to securely
@@ -229,7 +225,7 @@ Service
 
 .. versionadded:: 7.2
 
-    The ``Sipgate`` integration was introduced in Symfony 7.2.
+    The ``Primotexto`` and ``Sipgate`` integrations were introduced in Symfony 7.2.
 
 .. deprecated:: 7.1
 

From 12dfa63405ec8b7413ec69fa6df8306ce445d648 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 14 Oct 2024 15:46:52 +0200
Subject: [PATCH 390/747] Minor tweaks

---
 .../forms/types/options/choice_lazy.rst.inc   | 28 +++++++++----------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/reference/forms/types/options/choice_lazy.rst.inc b/reference/forms/types/options/choice_lazy.rst.inc
index db8591a613d..bdcbf178406 100644
--- a/reference/forms/types/options/choice_lazy.rst.inc
+++ b/reference/forms/types/options/choice_lazy.rst.inc
@@ -3,9 +3,13 @@
 
 **type**: ``boolean`` **default**: ``false``
 
-The ``choice_lazy`` option is especially useful when dealing with a large set of
-choices, where loading all of them at once could lead to performance issues or
-significant delays::
+.. versionadded:: 7.2
+
+    The ``choice_lazy`` option was introduced in Symfony 7.2.
+
+The ``choice_lazy`` option is particularly useful when dealing with a large set
+of choices, where loading them all at once could cause performance issues or
+delays::
 
     use App\Entity\User;
     use Symfony\Bridge\Doctrine\Form\Type\EntityType;
@@ -15,17 +19,13 @@ significant delays::
         'choice_lazy' => true,
     ]);
 
-When set to ``true``, and used in combination with the ``choice_loader`` option,
-the form will only load and render the choices that are preset as default values
-or submitted. This allows you to defer loading the full list of choices and can
-improve the performance of your form.
+When set to ``true`` and used alongside the ``choice_loader`` option, the form
+will only load and render the choices that are preset as default values or
+submitted. This defers the loading of the full list of choices, helping to
+improve your form's performance.
 
 .. caution::
 
-    Please note that when using ``choice_lazy``, you are responsible for providing
-    the user interface to select choices, typically through a JavaScript plugin that
-    can handle the dynamic loading of choices.
-
-.. versionadded:: 7.2
-
-    The ``choice_lazy`` option was introduced in Symfony 7.2.
+    Keep in mind that when using ``choice_lazy``, you are responsible for
+    providing the user interface for selecting choices, typically through a
+    JavaScript plugin capable of dynamically loading choices.

From 902d7500886526a147f564d8061a8140d3aa0c45 Mon Sep 17 00:00:00 2001
From: seb-jean <sebastien.jean76@gmail.com>
Date: Mon, 14 Oct 2024 20:39:46 +0200
Subject: [PATCH 391/747] Update controller.rst

---
 controller.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/controller.rst b/controller.rst
index 17cf30e40ef..4fd03948ae2 100644
--- a/controller.rst
+++ b/controller.rst
@@ -578,7 +578,7 @@ To do so, map the parameter as an array and configure the type of each element
 using the ``type`` option of the attribute::
 
     public function dashboard(
-        #[MapRequestPayload(type: UserDTO::class)] array $users
+        #[MapRequestPayload(type: UserDto::class)] array $users
     ): Response
     {
         // ...

From 93ca37815417a6c11b7d8807beec1d9bf111b557 Mon Sep 17 00:00:00 2001
From: Laurens Laman <laurens.laman@llaman.nl>
Date: Tue, 15 Oct 2024 14:56:21 +0200
Subject: [PATCH 392/747] Update progressindicator.rst

Corrected false statement about the finishedIndicator. Make documentation more clear
---
 .../console/helpers/progressindicator.rst     | 24 +++++++++++--------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/components/console/helpers/progressindicator.rst b/components/console/helpers/progressindicator.rst
index fedc8439e64..1d4384958e9 100644
--- a/components/console/helpers/progressindicator.rst
+++ b/components/console/helpers/progressindicator.rst
@@ -44,18 +44,21 @@ level of verbosity of the ``OutputInterface`` instance:
      | Processing...
      / Processing...
      - Processing...
+     ✔ Finished
 
     # OutputInterface::VERBOSITY_VERBOSE (-v)
      \ Processing... (1 sec)
      | Processing... (1 sec)
      / Processing... (1 sec)
      - Processing... (1 sec)
+     ✔ Finished (1 sec)
 
     # OutputInterface::VERBOSITY_VERY_VERBOSE (-vv) and OutputInterface::VERBOSITY_DEBUG (-vvv)
      \ Processing... (1 sec, 6.0 MiB)
      | Processing... (1 sec, 6.0 MiB)
      / Processing... (1 sec, 6.0 MiB)
      - Processing... (1 sec, 6.0 MiB)
+     ✔ Finished (1 sec, 6.0 MiB)
 
 .. tip::
 
@@ -94,22 +97,23 @@ The progress indicator will now look like this:
      ⠛ Processing...
      ⠹ Processing...
      ⢸ Processing...
+     ✔ Finished
 
-Once the progress indicator is finished, it keeps the latest indicator value by
-default. You can replace it with your own::
+Once the progress indicator is finished, it uses the finishedIndicator value (which defaults to ✔). You can replace it with your own::
 
-    $progressIndicator->finish('Finished', '✅');
-
-Then the progress indicator will render like this:
-
-.. code-block:: text
+    $progressIndicator = new ProgressIndicator($output, 'verbose', 100, null, '🎉');
+    
+    try {
+        /* do something */
+        $progressIndicator->finish('Finished');
+    } catch (\Exception) {
+        $progressIndicator->finish('Failed', '🚨');
+    }
 
-     ⠏ Processing...
-     ⠛ Processing...
-     ✅ Finished
 
 .. versionadded:: 7.2
 
+    The ``finishedIndicator`` parameter for the constructor was introduced in Symfony 7.2.
     The ``finishedIndicator`` parameter for method ``finish()`` was introduced in Symfony 7.2.
 
 Customize Placeholders

From 7fff76bd4fa1367554b959598c505dee6f4489e5 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Tue, 15 Oct 2024 16:36:14 +0200
Subject: [PATCH 393/747] rename addHeader to setHeader in httpclient

---
 http_client.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/http_client.rst b/http_client.rst
index 91b91ebc4a5..bf64026b946 100644
--- a/http_client.rst
+++ b/http_client.rst
@@ -152,7 +152,7 @@ brings most of the available options with type-hinted getters and setters::
             ->setBaseUri('https://...')
             // replaces *all* headers at once, and deletes the headers you do not provide
             ->setHeaders(['header-name' => 'header-value'])
-            // set or replace a single header using addHeader()
+            // set or replace a single header using setHeader()
             ->setHeader('another-header-name', 'another-header-value')
             ->toArray()
     );

From d926bbb4e7cb2cd75e0f2f444a3b41dc3a1938d5 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 16 Oct 2024 10:53:34 +0200
Subject: [PATCH 394/747] Reword

---
 messenger.rst | 102 +++++++++++++++++++++++++-------------------------
 1 file changed, 50 insertions(+), 52 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index 03c429e214e..9cb6b4a6ff4 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -203,8 +203,23 @@ Routing Messages to a Transport
 Now that you have a transport configured, instead of handling a message immediately,
 you can configure them to be sent to a transport:
 
+.. _messenger-message-attribute:
+
 .. configuration-block::
 
+    .. code-block:: php-attributes
+
+        // src/Message/SmsNotification.php
+        namespace App\Message;
+
+        use Symfony\Component\Messenger\Attribute\AsMessage;
+
+        #[AsMessage('async')]
+        class SmsNotification
+        {
+            // ...
+        }
+
     .. code-block:: yaml
 
         # config/packages/messenger.yaml
@@ -251,15 +266,26 @@ you can configure them to be sent to a transport:
             ;
         };
 
+.. versionadded:: 7.2
+
+    The ``#[AsMessage]`` attribute was introduced in Symfony 7.2.
+
 Thanks to this, the ``App\Message\SmsNotification`` will be sent to the ``async``
 transport and its handler(s) will *not* be called immediately. Any messages not
 matched under ``routing`` will still be handled immediately, i.e. synchronously.
 
 .. note::
 
-    You may use a partial PHP namespace like ``'App\Message\*'`` to match all
-    the messages within the matching namespace. The only requirement is that the
-    ``'*'`` wildcard has to be placed at the end of the namespace.
+    If you configure routing with both YAML/XML/PHP configuration files and
+    PHP attributes, the configuration always takes precedence over the class
+    attribute. This behavior allows you to override routing on a per-environment basis.
+
+.. note::
+
+    When configuring the routing in separate YAML/XML/PHP files, you can use a partial
+    PHP namespace like ``'App\Message\*'`` to match all the messages within the
+    matching namespace. The only requirement is that the ``'*'`` wildcard has to
+    be placed at the end of the namespace.
 
     You may use ``'*'`` as the message class. This will act as a default routing
     rule for any message not matched under ``routing``. This is useful to ensure
@@ -275,6 +301,27 @@ to multiple transports:
 
 .. configuration-block::
 
+    .. code-block:: php-attributes
+
+        // src/Message/SmsNotification.php
+        namespace App\Message;
+
+        use Symfony\Component\Messenger\Attribute\AsMessage;
+
+        #[AsMessage(['async', 'audit'])]
+        class SmsNotification
+        {
+            // ...
+        }
+
+        // if you prefer, you can also apply multiple attributes to the message class
+        #[AsMessage('async')]
+        #[AsMessage('audit')]
+        class SmsNotification
+        {
+            // ...
+        }
+
     .. code-block:: yaml
 
         # config/packages/messenger.yaml
@@ -345,55 +392,6 @@ to multiple transports:
     name as its only argument. For more information about stamps, see
     `Envelopes & Stamps`_.
 
-.. _messenger-message-attribute:
-
-Configuring Routing Using Attributes
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-You can optionally use the `#[AsMessage]` attribute to configure message transport::
-
-    // src/Message/SmsNotification.php
-    namespace App\Message;
-
-    use Symfony\Component\Messenger\Attribute\AsMessage;
-
-    #[AsMessage(transport: 'async')]
-    class SmsNotification
-    {
-        public function __construct(
-            private string $content,
-        ) {
-        }
-
-        public function getContent(): string
-        {
-            return $this->content;
-        }
-    }
-
-.. note::
-
-    If you configure routing with both configuration and attributes, the
-    configuration will take precedence over the attributes and override
-    them. This allows to override routing on a per-environment basis
-    for example:
-
-    .. code-block:: yaml
-
-        # config/packages/messenger.yaml
-        when@dev:
-            framework:
-                messenger:
-                    routing:
-                        # override class attribute
-                        'App\Message\SmsNotification': sync
-
-.. tip::
-
-    The `$transport` parameter can be either a `string` or an `array`: configuring multiple
-    transports is possible. You may also repeat the attribute if you prefer instead of using
-    an array.
-
 Doctrine Entities in Messages
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From 9d85b6904c11777c31263b276152ad980cbd08fc Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 16 Oct 2024 16:43:56 +0200
Subject: [PATCH 395/747] Tweaks

---
 components/console/helpers/progressindicator.rst | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/components/console/helpers/progressindicator.rst b/components/console/helpers/progressindicator.rst
index 1d4384958e9..0defe7c83fd 100644
--- a/components/console/helpers/progressindicator.rst
+++ b/components/console/helpers/progressindicator.rst
@@ -99,9 +99,10 @@ The progress indicator will now look like this:
      ⢸ Processing...
      ✔ Finished
 
-Once the progress indicator is finished, it uses the finishedIndicator value (which defaults to ✔). You can replace it with your own::
+Once the progress finishes, it displays a special finished indicator (which defaults
+to ✔). You can replace it with your own::
 
-    $progressIndicator = new ProgressIndicator($output, 'verbose', 100, null, '🎉');
+    $progressIndicator = new ProgressIndicator($output, finishedIndicatorValue: '🎉');
     
     try {
         /* do something */
@@ -110,6 +111,15 @@ Once the progress indicator is finished, it uses the finishedIndicator value (wh
         $progressIndicator->finish('Failed', '🚨');
     }
 
+The progress indicator will now look like this:
+
+.. code-block:: text
+
+     \ Processing...
+     | Processing...
+     / Processing...
+     - Processing...
+     🎉 Finished
 
 .. versionadded:: 7.2
 

From 6473d6c91f016b26b28ec8dc083fc300b0525133 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 16 Oct 2024 16:50:50 +0200
Subject: [PATCH 396/747] Finished the docs

---
 security/user_checkers.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/security/user_checkers.rst b/security/user_checkers.rst
index 1e1dcaf3e55..ec8f49da522 100644
--- a/security/user_checkers.rst
+++ b/security/user_checkers.rst
@@ -21,6 +21,8 @@ displayed to the user::
     namespace App\Security;
 
     use App\Entity\User as AppUser;
+    use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+    use Symfony\Component\Security\Core\Exception\AccessDeniedException;
     use Symfony\Component\Security\Core\Exception\AccountExpiredException;
     use Symfony\Component\Security\Core\Exception\CustomUserMessageAccountStatusException;
     use Symfony\Component\Security\Core\User\UserCheckerInterface;
@@ -50,9 +52,17 @@ displayed to the user::
             if ($user->isExpired()) {
                 throw new AccountExpiredException('...');
             }
+
+            if (!\in_array('foo', $token->getRoleNames())) {
+                throw new AccessDeniedException('...');
+            }
         }
     }
 
+.. versionadded:: 7.2
+
+    The ``token`` argument for the ``checkPostAuth()`` method was introduced in Symfony 7.2.
+
 Enabling the Custom User Checker
 --------------------------------
 

From f932585d967262ffcd0f2b63ac47faa043e9d3bf Mon Sep 17 00:00:00 2001
From: Mathieu Santostefano <msantostefano@protonmail.com>
Date: Sat, 19 Oct 2024 16:52:24 +0200
Subject: [PATCH 397/747] Add Sweego Notifier doc

---
 notifier.rst | 6 +++++-
 webhook.rst  | 1 +
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/notifier.rst b/notifier.rst
index b2329b2b28a..144044ebe3e 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -187,6 +187,9 @@ Service
 `SpotHit`_          **Install**: ``composer require symfony/spot-hit-notifier`` \
                     **DSN**: ``spothit://TOKEN@default?from=FROM`` \
                     **Webhook support**: No
+`Sweego`_           **Install**: ``composer require symfony/sweego-notifier`` \
+                    **DSN**: ``sweego://API_KEY@default?region=REGION&campaign_type=CAMPAIGN_TYPE`` \
+                    **Webhook support**: Yes
 `Telnyx`_           **Install**: ``composer require symfony/telnyx-notifier`` \
                     **DSN**: ``telnyx://API_KEY@default?from=FROM&messaging_profile_id=MESSAGING_PROFILE_ID`` \
                     **Webhook support**: No
@@ -225,7 +228,7 @@ Service
 
 .. versionadded:: 7.2
 
-    The ``Primotexto`` and ``Sipgate`` integrations were introduced in Symfony 7.2.
+    The ``Primotexto``, ``Sipgate`` and ``Sweego`` integrations were introduced in Symfony 7.2.
 
 .. deprecated:: 7.1
 
@@ -1239,6 +1242,7 @@ is dispatched. Listeners receive a
 .. _`SMSense`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SMSense/README.md
 .. _`SmsSluzba`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SmsSluzba/README.md
 .. _`SpotHit`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/SpotHit/README.md
+.. _`Sweego`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Sweego/README.md
 .. _`Telegram`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Telegram/README.md
 .. _`Telnyx`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Telnyx/README.md
 .. _`TurboSms`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/TurboSms/README.md
diff --git a/webhook.rst b/webhook.rst
index 6b79da037e4..aba95cffb04 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -166,6 +166,7 @@ Currently, the following third-party SMS transports support webhooks:
 SMS service  Parser service name
 ============ ==========================================
 Twilio       ``notifier.webhook.request_parser.twilio``
+Sweego       ``notifier.webhook.request_parser.sweego``
 Vonage       ``notifier.webhook.request_parser.vonage``
 ============ ==========================================
 

From ef9baef15df2f02bec0221f78cbab3151695f542 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Mon, 21 Oct 2024 08:56:56 +0200
Subject: [PATCH 398/747] fix param name for lint:translations

---
 translation.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/translation.rst b/translation.rst
index 4663d9d7c15..a1d012f3b38 100644
--- a/translation.rst
+++ b/translation.rst
@@ -1405,7 +1405,7 @@ to check that the translation contents are also correct:
         $ php bin/console lint:translations
 
         # checks the contents of the translation catalogues for Italian (it) and Japanese (ja) locales
-        $ php bin/console lint:translations --locales=it --locales=ja
+        $ php bin/console lint:translations --locale=it --locale=ja
 
 .. versionadded:: 7.2
 

From b8e5d0c59bf7a287687317026f56b7f5cd8d1f03 Mon Sep 17 00:00:00 2001
From: Jawira Portugal <dev@tugal.be>
Date: Sun, 27 Oct 2024 19:23:45 +0100
Subject: [PATCH 399/747] Add --prefix and --no-fill to translation page

---
 translation.rst | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/translation.rst b/translation.rst
index a1d012f3b38..2bbce00977a 100644
--- a/translation.rst
+++ b/translation.rst
@@ -467,8 +467,33 @@ The ``translation:extract`` command looks for missing translations in:
 
         $ composer require nikic/php-parser
 
+By default, the ``translation:extract`` command extracts new messages in
+*message/translation* pairs, with the translation populated with the same
+text as the message, prefixed by ``__``. You can customize this prefix using
+the ``--prefix`` option.
+
+If you want to leave new translations empty, use the ``--no-fill`` option.
+When enabled, only messages are created, and the translation strings are left
+empty. This is particularly useful when using external translation tools, as
+it ensures untranslated strings are easily identifiable without any pre-filled
+content. Note that when ``--no-fill`` is used, the ``--prefix`` option has
+no effect.
+
+.. code-block:: terminal
+
+    # changes default prefix
+    $ php bin/console translation:extract --force --prefix="NEW_" fr
+
+    # leaves new translations empty
+    $ php bin/console translation:extract --force --no-fill fr
+
+.. versionadded:: 7.2
+
+    The ``--no-fill`` option was introduced in Symfony 7.2.
+
 .. _translation-resource-locations:
 
+
 Translation Resource/File Names and Locations
 ---------------------------------------------
 

From 65a14d07553951cf305069d4d56485898d8121b6 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 28 Oct 2024 17:59:56 +0100
Subject: [PATCH 400/747] Minor tweaks

---
 translation.rst | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/translation.rst b/translation.rst
index 2bbce00977a..a41b305dc8b 100644
--- a/translation.rst
+++ b/translation.rst
@@ -467,24 +467,23 @@ The ``translation:extract`` command looks for missing translations in:
 
         $ composer require nikic/php-parser
 
-By default, the ``translation:extract`` command extracts new messages in
-*message/translation* pairs, with the translation populated with the same
-text as the message, prefixed by ``__``. You can customize this prefix using
-the ``--prefix`` option.
-
-If you want to leave new translations empty, use the ``--no-fill`` option.
-When enabled, only messages are created, and the translation strings are left
-empty. This is particularly useful when using external translation tools, as
-it ensures untranslated strings are easily identifiable without any pre-filled
-content. Note that when ``--no-fill`` is used, the ``--prefix`` option has
-no effect.
+By default, when the ``translation:extract`` command creates new entries in the
+trnaslation file, it uses the same content as both the source and the pending
+translation. The only difference is that the pending translation is prefixed by
+``__``. You can customize this prefix using the ``--prefix`` option:
 
 .. code-block:: terminal
 
-    # changes default prefix
     $ php bin/console translation:extract --force --prefix="NEW_" fr
 
-    # leaves new translations empty
+Alternatively, you can use the ``--no-fill`` option to leave the pending translation
+completely empty when creating new entries in the translation catalog. This is
+particularly useful when using external translation tools, as it makes it easier
+to spot untranslated strings:
+
+.. code-block:: terminal
+
+    # when using the --no-fill option, the --prefix option is ignored
     $ php bin/console translation:extract --force --no-fill fr
 
 .. versionadded:: 7.2
@@ -493,7 +492,6 @@ no effect.
 
 .. _translation-resource-locations:
 
-
 Translation Resource/File Names and Locations
 ---------------------------------------------
 

From 562893be94672b5987b74521d8abebac4d618d30 Mon Sep 17 00:00:00 2001
From: Jawira Portugal <dev@tugal.be>
Date: Mon, 28 Oct 2024 22:10:26 +0100
Subject: [PATCH 401/747] fix typo

---
 translation.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/translation.rst b/translation.rst
index a41b305dc8b..0e5f09d342e 100644
--- a/translation.rst
+++ b/translation.rst
@@ -468,7 +468,7 @@ The ``translation:extract`` command looks for missing translations in:
         $ composer require nikic/php-parser
 
 By default, when the ``translation:extract`` command creates new entries in the
-trnaslation file, it uses the same content as both the source and the pending
+translation file, it uses the same content as both the source and the pending
 translation. The only difference is that the pending translation is prefixed by
 ``__``. You can customize this prefix using the ``--prefix`` option:
 

From e033e433ab3d65e88fc5470662ecc485fc3117a6 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 29 Oct 2024 10:07:55 +0100
Subject: [PATCH 402/747] [Notifier] Add some examples to the new Desktop
 channel notifications

---
 notifier.rst | 71 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 61 insertions(+), 10 deletions(-)

diff --git a/notifier.rst b/notifier.rst
index 144044ebe3e..b28bb541475 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -33,8 +33,14 @@ The notifier component supports the following channels:
   services like Slack and Telegram;
 * :ref:`Email channel <notifier-email-channel>` integrates the :doc:`Symfony Mailer </mailer>`;
 * Browser channel uses :ref:`flash messages <flash-messages>`.
-* :ref:`Push channel <notifier-push-channel>` sends notifications to phones and browsers via push notifications.
-* :ref:`Desktop channel <notifier-desktop-channel>` displays desktop notifications on the same host machine.
+* :ref:`Push channel <notifier-push-channel>` sends notifications to phones and
+  browsers via push notifications.
+* :ref:`Desktop channel <notifier-desktop-channel>` displays desktop notifications
+  on the same host machine.
+
+.. versionadded:: 7.2
+
+    The ``Desktop`` channel was introduced in Symfony 7.2.
 
 .. _notifier-sms-channel:
 
@@ -635,9 +641,9 @@ configure the ``texter_transports``:
 Desktop Channel
 ~~~~~~~~~~~~~~~
 
-The desktop channel is used to display desktop notifications on the same host machine using
-:class:`Symfony\\Component\\Notifier\\Texter` classes. Currently, Symfony
-is integrated with the following providers:
+The desktop channel is used to display local desktop notifications on the same
+host machine using :class:`Symfony\\Component\\Notifier\\Texter` classes. Currently,
+Symfony is integrated with the following providers:
 
 ===============  ====================================  ==============================================================================
 Provider         Package                               DSN
@@ -645,18 +651,23 @@ Provider         Package                               DSN
 `JoliNotif`_     ``symfony/joli-notif-notifier``       ``jolinotif://default``
 ===============  ====================================  ==============================================================================
 
-.. versionadded: 7.2
+.. versionadded:: 7.2
 
     The JoliNotif bridge was introduced in Symfony 7.2.
 
-To enable a texter, add the correct DSN in your ``.env`` file and
-configure the ``texter_transports``:
+If you are using :ref:`Symfony Flex <symfony-flex>`, installing that package will
+also create the necessary environment variable and configuration. Otherwise, you'll
+need to add the following manually:
+
+1) Add the correct DSN in your ``.env`` file:
 
 .. code-block:: bash
 
     # .env
     JOLINOTIF=jolinotif://default
 
+2) Update the Notifier configuration to add a new texter transport:
+
 .. configuration-block::
 
     .. code-block:: yaml
@@ -699,9 +710,49 @@ configure the ``texter_transports``:
             ;
         };
 
-.. versionadded:: 7.2
+Now you can send notifications to your desktop as follows::
 
-    The ``Desktop`` channel was introduced in Symfony 7.2.
+    // src/Notifier/SomeService.php
+    use Symfony\Component\Notifier\Message\DesktopMessage;
+    use Symfony\Component\Notifier\TexterInterface;
+    // ...
+
+    class SomeService
+    {
+        public function __construct(
+            private TexterInterface $texter,
+        ) {
+        }
+
+        public function notifyNewSubscriber(User $user): void
+        {
+            $message = new DesktopMessage(
+                'New subscription! 🎉',
+                sprintf('%s is a new subscriber', $user->getFullName())
+            );
+
+            $texter->send($message);
+        }
+    }
+
+These notifications can be customized further, and depending on your operating system,
+they may support features like custom sounds, icons, and more::
+
+    use Symfony\Component\Notifier\Bridge\JoliNotif\JoliNotifOptions;
+    // ...
+
+    $options = (new JoliNotifOptions())
+        ->setIconPath('/path/to/icons/error.png')
+        ->setExtraOption('sound', 'sosumi')
+        ->setExtraOption('url', 'https://example.com');
+
+    $message = new DesktopMessage('Production is down', <<<CONTENT
+        ❌ Server prod-1 down
+        ❌ Server prod-2 down
+        ✅ Network is up
+        CONTENT, $options);
+
+    $texter->send($message);
 
 Configure to use Failover or Round-Robin Transports
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

From d20ac34ac17254dc48a74ced515948a825ceae35 Mon Sep 17 00:00:00 2001
From: Raffaele Carelle <raffaele.carelle@algoritma.it>
Date: Mon, 4 Nov 2024 09:48:23 +0100
Subject: [PATCH 403/747] add stringNode documentation

---
 components/config/definition.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/components/config/definition.rst b/components/config/definition.rst
index 929246fa915..05f64497a66 100644
--- a/components/config/definition.rst
+++ b/components/config/definition.rst
@@ -83,6 +83,12 @@ reflect the real structure of the configuration values::
             ->scalarNode('default_connection')
                 ->defaultValue('mysql')
             ->end()
+            ->stringNode('username')
+                ->defaultValue('root')
+            ->end()
+            ->stringNode('password')
+                ->defaultValue('root')
+            ->end()
         ->end()
     ;
 
@@ -100,6 +106,7 @@ node definition. Node types are available for:
 * scalar (generic type that includes booleans, strings, integers, floats
   and ``null``)
 * boolean
+* string
 * integer
 * float
 * enum (similar to scalar, but it only allows a finite set of values)

From 1a72556ae9bc4cc769fac8e81d950fc0afb2c6ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Maxime=20H=C3=A9lias?= <maximehelias16@gmail.com>
Date: Thu, 7 Nov 2024 13:26:14 +0100
Subject: [PATCH 404/747] [DependencyInjection] fix attribute first element

---
 service_container/service_decoration.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/service_container/service_decoration.rst b/service_container/service_decoration.rst
index 97c4c25090b..0f75b5284c8 100644
--- a/service_container/service_decoration.rst
+++ b/service_container/service_decoration.rst
@@ -630,7 +630,7 @@ Three different behaviors are available:
             class Bar
             {
                 public function __construct(
-                    private #[AutowireDecorated] $inner,
+                    #[AutowireDecorated] private $inner,
                 ) {
                 }
 

From 970d37b45d9b609376ce7c77f8a8384d954f509f Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 7 Nov 2024 16:47:56 +0100
Subject: [PATCH 405/747] Add the versionadded directives

---
 components/config/definition.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/components/config/definition.rst b/components/config/definition.rst
index 05f64497a66..4e99fb4f6a7 100644
--- a/components/config/definition.rst
+++ b/components/config/definition.rst
@@ -92,6 +92,10 @@ reflect the real structure of the configuration values::
         ->end()
     ;
 
+.. versionadded:: 7.2
+
+    The ``stringNode()`` method was introduced in Symfony 7.2.
+
 The root node itself is an array node, and has children, like the boolean
 node ``auto_connect`` and the scalar node ``default_connection``. In general:
 after defining a node, a call to ``end()`` takes you one step up in the
@@ -116,6 +120,10 @@ node definition. Node types are available for:
 and are created with ``node($name, $type)`` or their associated shortcut
 ``xxxxNode($name)`` method.
 
+.. versionadded::
+
+    Support for ``string`` types was introduced in Symfony 7.2.
+
 Numeric Node Constraints
 ~~~~~~~~~~~~~~~~~~~~~~~~
 

From 7eb2264b2f1dff013aed0a9ffd32c6974f3f1270 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Fri, 8 Nov 2024 14:45:59 +0100
Subject: [PATCH 406/747] fix versionadded directive

---
 components/config/definition.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/components/config/definition.rst b/components/config/definition.rst
index 4e99fb4f6a7..0db9923a340 100644
--- a/components/config/definition.rst
+++ b/components/config/definition.rst
@@ -120,9 +120,9 @@ node definition. Node types are available for:
 and are created with ``node($name, $type)`` or their associated shortcut
 ``xxxxNode($name)`` method.
 
-.. versionadded::
+.. versionadded:: 7.2
 
-    Support for ``string`` types was introduced in Symfony 7.2.
+    Support for the ``string`` type was introduced in Symfony 7.2.
 
 Numeric Node Constraints
 ~~~~~~~~~~~~~~~~~~~~~~~~

From 626d56ef5863b08a206196cb089a1d2c2557339c Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Sat, 9 Nov 2024 11:08:20 +0100
Subject: [PATCH 407/747] remove note about the reverted Default group change

---
 serializer.rst | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/serializer.rst b/serializer.rst
index 91fd92a39a3..bfd838bc4bb 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -385,18 +385,6 @@ stored in one of the following locations:
 * All ``*.yaml`` and ``*.xml`` files in the ``Resources/config/serialization/``
   directory of a bundle.
 
-.. note::
-
-    The groups used by default when normalizing and denormalizing objects are
-    ``Default`` and the group that matches the class name. For example, if you
-    are normalizing a ``App\Entity\Product`` object, the groups used are
-    ``Default`` and ``Product``.
-
-    .. versionadded:: 7.1
-
-        The default use of the class name and ``Default`` groups when normalizing
-        and denormalizing objects was introduced in Symfony 7.1.
-
 .. _serializer-enabling-metadata-cache:
 
 Using Nested Attributes

From 8ed98d3230446e82ee5dab677dc0afc8a9c53f66 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Mon, 11 Nov 2024 17:44:07 +0100
Subject: [PATCH 408/747] add a missing value in MacAdress constraint

---
 reference/constraints/MacAddress.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/reference/constraints/MacAddress.rst b/reference/constraints/MacAddress.rst
index 59adffe7c11..9a282ddf118 100644
--- a/reference/constraints/MacAddress.rst
+++ b/reference/constraints/MacAddress.rst
@@ -132,6 +132,7 @@ Parameter                         Allowed MAC addresses
 ``multicast_no_broadcast``        Only multicast except broadcast
 ``unicast_all``                   Only unicast
 ``universal_all``                 Only universal
+``universal_unicast``             Only universal and unicast
 ``universal_multicast``           Only universal and multicast
 ================================  =========================================
 

From f40f01b78d41fbf7ee52a6f5aba26d866f08129d Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Mon, 11 Nov 2024 17:22:23 +0100
Subject: [PATCH 409/747] [Validator] Improve type for the `mode` property of
 the `Bic` constraint

---
 reference/constraints/Bic.rst | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/reference/constraints/Bic.rst b/reference/constraints/Bic.rst
index 3f05e5eac25..313de3bdbbf 100644
--- a/reference/constraints/Bic.rst
+++ b/reference/constraints/Bic.rst
@@ -124,18 +124,13 @@ Parameter        Description
 ``mode``
 ~~~~~~~~
 
-**type**: ``string`` **default**: ``strict``
+**type**: ``string`` **default**: ``BIC::VALIDATION_MODE_STRICT``
 
-This option defines how the BIC is validated:
+This option defines how the BIC is validated. Available constants are defined
+in the :class:`Symfony\\Component\\Validator\\Constraints\\BIC` class.
 
-* ``strict`` validates the given value without any modification;
-* ``case-insensitive`` converts the given value to uppercase before validating it.
-
-.. tip::
-
-    The possible values of this option are also defined as PHP constants of
-    :class:`Symfony\\Component\\Validator\\Constraints\\BIC`
-    (e.g. ``BIC::VALIDATION_MODE_CASE_INSENSITIVE``).
+* ``BIC::VALIDATION_MODE_STRICT`` validates the given value without any modification;
+* ``BIC::VALIDATION_MODE_CASE_INSENSITIVE`` converts the given value to uppercase before validating it.
 
 .. versionadded:: 7.2
 

From bc8c2d222b0f89f92f630ac4de7e5674f9e11a35 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 13 Nov 2024 17:10:23 +0100
Subject: [PATCH 410/747] Minor tweaks

---
 reference/constraints/Bic.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/reference/constraints/Bic.rst b/reference/constraints/Bic.rst
index 313de3bdbbf..6cde4a11bac 100644
--- a/reference/constraints/Bic.rst
+++ b/reference/constraints/Bic.rst
@@ -124,13 +124,13 @@ Parameter        Description
 ``mode``
 ~~~~~~~~
 
-**type**: ``string`` **default**: ``BIC::VALIDATION_MODE_STRICT``
+**type**: ``string`` **default**: ``Bic::VALIDATION_MODE_STRICT``
 
-This option defines how the BIC is validated. Available constants are defined
-in the :class:`Symfony\\Component\\Validator\\Constraints\\BIC` class.
+This option defines how the BIC is validated. The possible values are available
+as constants in the :class:`Symfony\\Component\\Validator\\Constraints\\Bic` class:
 
-* ``BIC::VALIDATION_MODE_STRICT`` validates the given value without any modification;
-* ``BIC::VALIDATION_MODE_CASE_INSENSITIVE`` converts the given value to uppercase before validating it.
+* ``Bic::VALIDATION_MODE_STRICT`` validates the given value without any modification;
+* ``Bic::VALIDATION_MODE_CASE_INSENSITIVE`` converts the given value to uppercase before validating it.
 
 .. versionadded:: 7.2
 

From 40058d823673436e935308a05acd87db028fbb7c Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Thu, 14 Nov 2024 08:39:36 +0100
Subject: [PATCH 411/747] the TypeInfo component is no longer experimental

---
 components/type_info.rst | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index 30ae11aa222..f46c8f8ab3a 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -11,11 +11,6 @@ This component provides:
 * A way to get types from PHP elements such as properties, method arguments,
   return types, and raw strings.
 
-.. caution::
-
-    This component is :doc:`experimental </contributing/code/experimental>` and
-    could be changed at any time without prior notice.
-
 Installation
 ------------
 

From 8b9ca6f5e9c1c4964cebc08b35de6344f5902870 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Sat, 16 Nov 2024 10:22:58 +0100
Subject: [PATCH 412/747] remove documentation about no longer existing
 getBaseType() method

---
 components/type_info.rst | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index f46c8f8ab3a..bbc7d0ea8dc 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -58,12 +58,6 @@ based on reflection or a simple string::
 
     // Type instances have several helper methods
 
-    // returns the main type (e.g. in this example it returns an "array" Type instance);
-    // for nullable types (e.g. string|null) it returns the non-null type (e.g. string)
-    // and for compound types (e.g. int|string) it throws an exception because both types
-    // can be considered the main one, so there's no way to pick one
-    $baseType = $type->getBaseType();
-
     // for collections, it returns the type of the item used as the key;
     // in this example, the collection is a list, so it returns an "int" Type instance
     $keyType = $type->getCollectionKeyType();

From 4eed10be822e64078281704b91b404b8803d2d3d Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Mon, 18 Nov 2024 09:44:26 +0100
Subject: [PATCH 413/747] mailersend support webhook

---
 mailer.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mailer.rst b/mailer.rst
index 6527fecaa16..b8421cc6d26 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -107,7 +107,7 @@ Service               Install with                                    Webhook su
 `Mailgun`_            ``composer require symfony/mailgun-mailer``     yes
 `Mailjet`_            ``composer require symfony/mailjet-mailer``     yes
 `MailPace`_           ``composer require symfony/mail-pace-mailer``
-`MailerSend`_         ``composer require symfony/mailer-send-mailer``
+`MailerSend`_         ``composer require symfony/mailer-send-mailer`` yes
 `Mandrill`_           ``composer require symfony/mailchimp-mailer``
 `Postmark`_           ``composer require symfony/postmark-mailer``    yes
 `Resend`_             ``composer require symfony/resend-mailer``      yes

From 2f8a9d656df47bbe5cdd25094ffb183af8aba376 Mon Sep 17 00:00:00 2001
From: Wouter de Jong <wouter@wouterj.nl>
Date: Sat, 23 Nov 2024 18:00:57 +0100
Subject: [PATCH 414/747] Syntax fixes

---
 serializer.rst                   | 2 +-
 serializer/custom_normalizer.rst | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/serializer.rst b/serializer.rst
index 6a12f689512..648b44670f1 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -1266,7 +1266,7 @@ normalizers (in order of priority):
 
     :phpclass:`DateTime` and :phpclass:`DateTimeImmutable`) into strings,
     integers or floats. By default, it converts them to strings using the
-    `RFC3339`_ format. Use ``DateTimeNormalizer::FORMAT_KEY`` and
+    `RFC 3339`_ format. Use ``DateTimeNormalizer::FORMAT_KEY`` and
     ``DateTimeNormalizer::TIMEZONE_KEY`` to change the format.
 
     To convert the objects to integers or floats, set the serializer
diff --git a/serializer/custom_normalizer.rst b/serializer/custom_normalizer.rst
index 26eacdeba0b..10092c6baa7 100644
--- a/serializer/custom_normalizer.rst
+++ b/serializer/custom_normalizer.rst
@@ -76,6 +76,7 @@ If you're not using ``autoconfigure``, you have to tag the service with
 .. configuration-block::
 
     .. code-block:: yaml
+
         # config/services.yaml
         services:
             # ...

From 337b5974e08ee43012ccd3ec6174f35409ccea41 Mon Sep 17 00:00:00 2001
From: Wouter de Jong <wouter@wouterj.nl>
Date: Sat, 23 Nov 2024 18:03:07 +0100
Subject: [PATCH 415/747] More syntax fixes

---
 serializer/encoders.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/serializer/encoders.rst b/serializer/encoders.rst
index 65eece78031..003eb4523fe 100644
--- a/serializer/encoders.rst
+++ b/serializer/encoders.rst
@@ -65,7 +65,7 @@ are available to customize the behavior of the encoder:
 ``csv_end_of_line`` (default: ``\n``)
     Sets the character(s) used to mark the end of each line in the CSV file.
 ``csv_escape_char`` (default: empty string)
-    .. deprecated::
+    .. deprecated:: 7.2
 
         The ``csv_escape_char`` option was deprecated in Symfony 7.2.
 

From dc999f33194b22851c44ba6147833b1e8003bc8f Mon Sep 17 00:00:00 2001
From: Baptiste Leduc <baptiste.leduc@gmail.com>
Date: Fri, 15 Nov 2024 10:20:18 +0100
Subject: [PATCH 416/747] Add more details to TypeInfo documentation

---
 components/type_info.rst | 100 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 97 insertions(+), 3 deletions(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index bbc7d0ea8dc..18556e02972 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -40,12 +40,24 @@ to the :class:`Symfony\\Component\\TypeInfo\\Type` static methods as following::
     // Many others are available and can be
     // found in Symfony\Component\TypeInfo\TypeFactoryTrait
 
+Resolvers
+~~~~~~~~~
+
 The second way of using the component is to use ``TypeInfo`` to resolve a type
-based on reflection or a simple string::
+based on reflection or a simple string, this is aimed towards libraries that wants to
+describe a class or anything that has a type easily::
 
     use Symfony\Component\TypeInfo\Type;
     use Symfony\Component\TypeInfo\TypeResolver\TypeResolver;
 
+    class Dummy
+    {
+        public function __construct(
+            public int $id,
+        ) {
+        }
+    }
+
     // Instantiate a new resolver
     $typeResolver = TypeResolver::create();
 
@@ -70,6 +82,88 @@ Each of these calls will return you a ``Type`` instance that corresponds to the
 static method used. You can also resolve types from a string (as shown in the
 ``bool`` parameter of the previous example)
 
-.. note::
+PHPDoc parsing
+~~~~~~~~~~~~~~
 
-    To support raw string resolving, you need to install ``phpstan/phpdoc-parser`` package.
+But most times you won't have clean typed properties or you want a more precise type
+thank to advanced PHPDoc, to do that you would want a string resolver based on that PHPDoc.
+First you will require ``phpstan/phpdoc-parser`` package from composer to support string
+revolving. Then you would do as following::
+
+    use Symfony\Component\TypeInfo\TypeResolver\TypeResolver;
+
+    class Dummy
+    {
+        public function __construct(
+            public int $id,
+            /** @var string[] $tags */
+            public array $tags,
+        ) {
+        }
+    }
+
+    $typeResolver = TypeResolver::create();
+    $typeResolver->resolve(new \ReflectionProperty(Dummy::class, 'id')); // returns an "int" Type
+    $typeResolver->resolve(new \ReflectionProperty(Dummy::class, 'id')); // returns a collection with "int" as key and "string" as values Type
+
+Advanced usages
+~~~~~~~~~~~~~~~
+
+There is many methods to manipulate and check types depending on your needs within the TypeInfo components.
+
+If you need a check a simple Type::
+
+    // You need to check if a Type
+    $type = Type::int(); // with a simple int type
+    // You can check if a given type comply with a given identifier
+    $type->isIdentifiedBy(TypeIdentifier::INT); // true
+    $type->isIdentifiedBy(TypeIdentifier::STRING); // false
+
+    $type = Type::union(Type::string(), Type::int()); // with an union of int and string types
+    // You can now see that the second check will pass to true since we have an union with a string type
+    $type->isIdentifiedBy(TypeIdentifier::INT); // true
+    $type->isIdentifiedBy(TypeIdentifier::STRING); // true
+
+    class DummyParent {}
+    class Dummy extends DummyParent implements DummyInterface {}
+    $type = Type::object(Dummy::class); // with an object Type
+    // You can check is the Type is an object, or even if it's a given class
+    $type->isIdentifiedBy(TypeIdentifier::OBJECT); // true
+    $type->isIdentifiedBy(Dummy::class); // true
+    // Or inherits/implements something
+    $type->isIdentifiedBy(DummyParent::class); // true
+    $type->isIdentifiedBy(DummyInterface::class); // true
+
+Sometimes you want to check for more than one thing at a time so a callable may be better to check everything::
+
+    class Foo
+    {
+        private int $integer;
+        private string $string;
+        private ?float $float;
+    }
+
+    $reflClass = new \ReflectionClass(Foo::class);
+
+    $resolver = TypeResolver::create();
+    $integerType = $resolver->resolve($reflClass->getProperty('integer'));
+    $stringType = $resolver->resolve($reflClass->getProperty('string'));
+    $floatType = $resolver->resolve($reflClass->getProperty('float'));
+
+    // your callable to check whatever you need
+    // here we want to validate a given type is a non nullable number
+    $isNonNullableNumber = function (Type $type): bool {
+        if ($type->isNullable()) {
+            return false;
+        }
+
+        if ($type->isIdentifiedBy(TypeIdentifier::INT) || $type->isIdentifiedBy(TypeIdentifier::FLOAT)) {
+            return true;
+        }
+
+        return false;
+    };
+
+    $integerType->isSatisfiedBy($isNonNullableNumber); // true
+    $stringType->isSatisfiedBy($isNonNullableNumber); // false
+    $floatType->isSatisfiedBy($isNonNullableNumber); // false

From 03b029b9f3d144573b16f94a56e51aa7666e1342 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Wed, 27 Nov 2024 06:36:46 +0100
Subject: [PATCH 417/747] minor cs fix for ci

---
 serializer/encoders.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/serializer/encoders.rst b/serializer/encoders.rst
index 003eb4523fe..e36d8731e48 100644
--- a/serializer/encoders.rst
+++ b/serializer/encoders.rst
@@ -65,6 +65,7 @@ are available to customize the behavior of the encoder:
 ``csv_end_of_line`` (default: ``\n``)
     Sets the character(s) used to mark the end of each line in the CSV file.
 ``csv_escape_char`` (default: empty string)
+
     .. deprecated:: 7.2
 
         The ``csv_escape_char`` option was deprecated in Symfony 7.2.

From e427a6cb7466dba166e17f446b0f5a210757c8b9 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Wed, 27 Nov 2024 06:18:03 +0100
Subject: [PATCH 418/747] [Security] Secret with remember me feature

---
 security/remember_me.rst | 25 ++++++++++---------------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/security/remember_me.rst b/security/remember_me.rst
index 8fac6d78849..2fd0f7e8d1e 100644
--- a/security/remember_me.rst
+++ b/security/remember_me.rst
@@ -19,7 +19,7 @@ the session lasts using a cookie with the ``remember_me`` firewall option:
                 main:
                     # ...
                     remember_me:
-                        secret:   '%kernel.secret%' # required
+                        secret: '%kernel.secret%'
                         lifetime: 604800 # 1 week in seconds
                         # by default, the feature is enabled by checking a
                         # checkbox in the login form (see below), uncomment the
@@ -44,7 +44,7 @@ the session lasts using a cookie with the ``remember_me`` firewall option:
                 <firewall name="main">
                     <!-- ... -->
 
-                    <!-- secret: required
+                    <!-- secret: default to "%kernel.secret%"
                          lifetime: 604800 is 1 week in seconds -->
                     <remember-me
                         secret="%kernel.secret%"
@@ -67,7 +67,7 @@ the session lasts using a cookie with the ``remember_me`` firewall option:
             $security->firewall('main')
                 // ...
                 ->rememberMe()
-                    ->secret('%kernel.secret%') // required
+                    ->secret('%kernel.secret%')
                     ->lifetime(604800) // 1 week in seconds
 
                     // by default, the feature is enabled by checking a
@@ -77,9 +77,11 @@ the session lasts using a cookie with the ``remember_me`` firewall option:
             ;
         };
 
-The ``secret`` option is the only required option and it is used to sign
-the remember me cookie. It's common to use the ``kernel.secret`` parameter,
-which is defined using the ``APP_SECRET`` environment variable.
+.. versionadded:: 7.2
+
+    The ``secret`` option is no longer required starting from Symfony 7.2. By
+    default, ``%kernel.secret%`` is used, which is defined using the
+    ``APP_SECRET`` environment variable.
 
 After enabling the ``remember_me`` system in the configuration, there are a
 couple more things to do before remember me works correctly:
@@ -171,7 +173,6 @@ allow users to opt-out. In these cases, you can use the
                 main:
                     # ...
                     remember_me:
-                        secret: '%kernel.secret%'
                         # ...
                         always_remember_me: true
 
@@ -194,7 +195,6 @@ allow users to opt-out. In these cases, you can use the
                     <!-- ... -->
 
                     <remember-me
-                        secret="%kernel.secret%"
                         always-remember-me="true"
                     />
                 </firewall>
@@ -211,7 +211,6 @@ allow users to opt-out. In these cases, you can use the
             $security->firewall('main')
                 // ...
                 ->rememberMe()
-                    ->secret('%kernel.secret%')
                     // ...
                     ->alwaysRememberMe(true)
             ;
@@ -335,7 +334,6 @@ are fetched from the user object using the
                 main:
                     # ...
                     remember_me:
-                        secret: '%kernel.secret%'
                         # ...
                         signature_properties: ['password', 'updatedAt']
 
@@ -357,7 +355,7 @@ are fetched from the user object using the
                 <firewall name="main">
                     <!-- ... -->
 
-                    <remember-me secret="%kernel.secret%">
+                    <remember-me>
                         <signature-property>password</signature-property>
                         <signature-property>updatedAt</signature-property>
                     </remember-me>
@@ -375,7 +373,6 @@ are fetched from the user object using the
             $security->firewall('main')
                 // ...
                 ->rememberMe()
-                    ->secret('%kernel.secret%')
                     // ...
                     ->signatureProperties(['password', 'updatedAt'])
             ;
@@ -419,7 +416,6 @@ You can enable the doctrine token provider using the ``doctrine`` setting:
                 main:
                     # ...
                     remember_me:
-                        secret: '%kernel.secret%'
                         # ...
                         token_provider:
                             doctrine: true
@@ -442,7 +438,7 @@ You can enable the doctrine token provider using the ``doctrine`` setting:
                 <firewall name="main">
                     <!-- ... -->
 
-                    <remember-me secret="%kernel.secret%">
+                    <remember-me>
                         <token-provider doctrine="true"/>
                     </remember-me>
                 </firewall>
@@ -459,7 +455,6 @@ You can enable the doctrine token provider using the ``doctrine`` setting:
             $security->firewall('main')
                 // ...
                 ->rememberMe()
-                    ->secret('%kernel.secret%')
                     // ...
                     ->tokenProvider([
                         'doctrine' => true,

From c71b9f93795d90f0ae377f17026173f1e1c949a5 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Mon, 2 Dec 2024 08:38:44 +0100
Subject: [PATCH 419/747] remove a gc_probability default mention

---
 session.rst | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/session.rst b/session.rst
index 393cd24a898..aa4c3ba381f 100644
--- a/session.rst
+++ b/session.rst
@@ -494,18 +494,7 @@ deleted. This allows one to expire records based on idle time.
 
 However, some operating systems (e.g. Debian) do their own session handling and set
 the ``session.gc_probability`` variable to ``0`` to stop PHP doing garbage
-collection. That's why Symfony now overwrites this value to ``1``.
-
-If you wish to use the original value set in your ``php.ini``, add the following
-configuration:
-
-.. code-block:: yaml
-
-    # config/packages/framework.yaml
-    framework:
-        session:
-            # ...
-            gc_probability: null
+collection.
 
 You can configure these settings by passing ``gc_probability``, ``gc_divisor``
 and ``gc_maxlifetime`` in an array to the constructor of
@@ -513,6 +502,10 @@ and ``gc_maxlifetime`` in an array to the constructor of
 or to the :method:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage::setOptions`
 method.
 
+.. versionadded:: 7.2
+
+    Starting from Symfony 7.2, ``php.ini``'s directive is used as default for ``gc_probability``.
+
 .. _session-database:
 
 Store Sessions in a Database

From 2083dc2eb14cc9b7d7213249d4d0437d36b997ce Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Mon, 2 Dec 2024 10:40:51 +0100
Subject: [PATCH 420/747] Allow integer for the calendar option of DateType

---
 reference/forms/types/date.rst | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/reference/forms/types/date.rst b/reference/forms/types/date.rst
index e88e91d80dd..6b8d21a19bd 100644
--- a/reference/forms/types/date.rst
+++ b/reference/forms/types/date.rst
@@ -156,11 +156,12 @@ values for the year, month and day fields::
 ``calendar``
 ~~~~~~~~~~~~
 
-**type**: ``\IntlCalendar`` **default**: ``null``
+**type**: ``integer`` or ``\IntlCalendar`` **default**: ``null``
 
 The calendar to use for formatting and parsing the date. The value should be
-an instance of the :phpclass:`IntlCalendar` to use. By default, the Gregorian
-calendar with the application default locale is used.
+an ``integer`` from :phpclass:`IntlDateFormatter` calendar constants or an instance
+of the :phpclass:`IntlCalendar` to use. By default, the Gregorian calendar
+with the application default locale is used.
 
 .. versionadded:: 7.2
 

From a0f7fab6e75ac4b76e21f5f412132f1bebed375a Mon Sep 17 00:00:00 2001
From: Morf <1416936+m0rff@users.noreply.github.com>
Date: Mon, 2 Dec 2024 16:10:23 +0100
Subject: [PATCH 421/747] fix: Update micro_kernel_trait.rst

---
 configuration/micro_kernel_trait.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configuration/micro_kernel_trait.rst b/configuration/micro_kernel_trait.rst
index c9739679f69..62e8c2d4128 100644
--- a/configuration/micro_kernel_trait.rst
+++ b/configuration/micro_kernel_trait.rst
@@ -16,7 +16,7 @@ via Composer:
 
 .. code-block:: terminal
 
-    $ composer symfony/framework-bundle symfony/runtime
+    $ composer require symfony/framework-bundle symfony/runtime
 
 Next, create an ``index.php`` file that defines the kernel class and runs it:
 

From 646e1995c71abf8b84e75c51cc355b1cc5e258b4 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Mon, 2 Dec 2024 10:13:27 +0100
Subject: [PATCH 422/747] [Messenger] Document `getRetryDelay()`

---
 messenger.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index 74f7d792436..aa46ef9b1d3 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1134,6 +1134,13 @@ and must be retried. If you throw
 :class:`Symfony\\Component\\Messenger\\Exception\\RecoverableMessageHandlingException`,
 the message will always be retried infinitely and ``max_retries`` setting will be ignored.
 
+If you want to override retry delay form the retry strategy. You can achieve this
+using by providing it in the exception, using the ``getRetryDelay()`` method from :class:`Symfony\\Component\\Messenger\\Exception\\RecoverableExceptionInterface`.
+
+.. versionadded:: 7.2
+
+    The method ``getRetryDelay()`` was introduced in Symfony 7.2.
+
 .. _messenger-failure-transport:
 
 Saving & Retrying Failed Messages

From f99ae716aeb01cc279f4def8386f4d4fa7d7c190 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 2 Dec 2024 16:21:58 +0100
Subject: [PATCH 423/747] Reword

---
 messenger.rst | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index 35db17a75b3..053ccfd172e 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1134,12 +1134,14 @@ and must be retried. If you throw
 :class:`Symfony\\Component\\Messenger\\Exception\\RecoverableMessageHandlingException`,
 the message will always be retried infinitely and ``max_retries`` setting will be ignored.
 
-If you want to override retry delay form the retry strategy. You can achieve this
-using by providing it in the exception, using the ``getRetryDelay()`` method from :class:`Symfony\\Component\\Messenger\\Exception\\RecoverableExceptionInterface`.
+You can define a custom retry delay (e.g., to use the value from the ``Retry-After``
+header in an HTTP response) by setting the ``retryDelay`` argument in the
+constructor of the ``RecoverableMessageHandlingException``.
 
 .. versionadded:: 7.2
 
-    The method ``getRetryDelay()`` was introduced in Symfony 7.2.
+    The ``retryDelay`` argument and the ``getRetryDelay()`` method were introduced
+    in Symfony 7.2.
 
 .. _messenger-failure-transport:
 

From 977be3230885146769f8304e9aa0a578b4cc372e Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 2 Dec 2024 16:34:09 +0100
Subject: [PATCH 424/747] Reword

---
 session.rst | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/session.rst b/session.rst
index aa4c3ba381f..e3f2246b6f6 100644
--- a/session.rst
+++ b/session.rst
@@ -492,19 +492,30 @@ the ``php.ini`` directive ``session.gc_maxlifetime``. The meaning in this contex
 that any stored session that was saved more than ``gc_maxlifetime`` ago should be
 deleted. This allows one to expire records based on idle time.
 
-However, some operating systems (e.g. Debian) do their own session handling and set
-the ``session.gc_probability`` variable to ``0`` to stop PHP doing garbage
-collection.
+However, some operating systems (e.g. Debian) manage session handling differently
+and set the ``session.gc_probability`` variable to ``0`` to prevent PHP from performing
+garbage collection. By default, Symfony uses the value of the ``gc_probability``
+directive set in the ``php.ini`` file. If you can't modify this PHP setting, you
+can configure it directly in Symfony:
 
-You can configure these settings by passing ``gc_probability``, ``gc_divisor``
-and ``gc_maxlifetime`` in an array to the constructor of
+.. code-block:: yaml
+
+    # config/packages/framework.yaml
+    framework:
+        session:
+            # ...
+            gc_probability: 1
+
+Alternatively, you can configure these settings by passing ``gc_probability``,
+``gc_divisor`` and ``gc_maxlifetime`` in an array to the constructor of
 :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage`
 or to the :method:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage::setOptions`
 method.
 
 .. versionadded:: 7.2
 
-    Starting from Symfony 7.2, ``php.ini``'s directive is used as default for ``gc_probability``.
+    Using the ``php.ini`` directive as the default value for ``gc_probability``
+    was introduced in Symfony 7.2.
 
 .. _session-database:
 

From 00a781fdd643e516a6f196e84e765716e5a99e44 Mon Sep 17 00:00:00 2001
From: Thomas Landauer <thomas@landauer.at>
Date: Mon, 2 Dec 2024 17:25:05 +0100
Subject: [PATCH 425/747] Update mailer.rst: Changing order of tips

Page: https://symfony.com/doc/current/mailer.html#email-addresses

Reason: Bring the 2 IDN-related tips together.
---
 mailer.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index 8ff13c2561a..9cfba6c1a71 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -560,17 +560,17 @@ both strings or address objects::
         // ...
     ;
 
-.. versionadded:: 7.2
-
-    Support for non-ASCII email addresses (e.g. ``jânë.dœ@ëxãmplę.com``)
-    was introduced in Symfony 7.2.
-
 .. tip::
 
     Instead of calling ``->from()`` *every* time you create a new email, you can
     :ref:`configure emails globally <mailer-configure-email-globally>` to set the
     same ``From`` email to all messages.
 
+.. versionadded:: 7.2
+
+    Support for non-ASCII email addresses (e.g. ``jânë.dœ@ëxãmplę.com``)
+    was introduced in Symfony 7.2.
+
 .. note::
 
     The local part of the address (what goes before the ``@``) can include UTF-8

From ec2743dd19e580971b8707eff6a66edcdf9f10a2 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Tue, 3 Dec 2024 12:05:33 +0100
Subject: [PATCH 426/747] [HttpFoundation] Do not use named parameters in
 example

---
 components/http_foundation.rst | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/components/http_foundation.rst b/components/http_foundation.rst
index 4dcf3b1e4da..c91ec5ced8f 100644
--- a/components/http_foundation.rst
+++ b/components/http_foundation.rst
@@ -367,11 +367,13 @@ of the ``anonymize()`` method to specify the number of bytes that should be
 anonymized depending on the IP address format::
 
     $ipv4 = '123.234.235.236';
-    $anonymousIpv4 = IpUtils::anonymize($ipv4, v4Bytes: 3);
+    $anonymousIpv4 = IpUtils::anonymize($ipv4, 3);
     // $anonymousIpv4 = '123.0.0.0'
 
     $ipv6 = '2a01:198:603:10:396e:4789:8e99:890f';
-    $anonymousIpv6 = IpUtils::anonymize($ipv6, v6Bytes: 10);
+    // (you must define the second argument (bytes to anonymize in IPv4 addresses)
+    // even when you are only anonymizing IPv6 addresses)
+    $anonymousIpv6 = IpUtils::anonymize($ipv6, 3, 10);
     // $anonymousIpv6 = '2a01:198:603::'
 
 .. versionadded:: 7.2

From a8841ee2472df97291395786dbdbf68d551db348 Mon Sep 17 00:00:00 2001
From: kl3sk <klesk44@gmail.com>
Date: Mon, 28 Oct 2024 12:27:32 +0100
Subject: [PATCH 427/747] Update Expression_language: lint function

The lint function doesn't return anything but exception.

Second arguments with Flags example is ommitted.

Update expression_language.rst

Removing `var_dump`, this make no sens here.

Update expression_language.rst

Sync with last commits

Update expression_language.rst

Change comment explication for "IGNORE_*" flags
---
 components/expression_language.rst | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/components/expression_language.rst b/components/expression_language.rst
index 785beebd9da..7dacf581b14 100644
--- a/components/expression_language.rst
+++ b/components/expression_language.rst
@@ -106,6 +106,10 @@ if the expression is not valid::
 
     $expressionLanguage->lint('1 + 2', []); // doesn't throw anything
 
+    $expressionLanguage->lint('1 + a', []);
+    // Throw SyntaxError Exception
+    // "Variable "a" is not valid around position 5 for expression `1 + a`."
+
 The behavior of these methods can be configured with some flags defined in the
 :class:`Symfony\\Component\\ExpressionLanguage\\Parser` class:
 
@@ -121,8 +125,8 @@ This is how you can use these flags::
 
     $expressionLanguage = new ExpressionLanguage();
 
-    // this returns true because the unknown variables and functions are ignored
-    var_dump($expressionLanguage->lint('unknown_var + unknown_function()', Parser::IGNORE_UNKNOWN_VARIABLES | Parser::IGNORE_UNKNOWN_FUNCTIONS));
+    // Does not throw a SyntaxError because the unknown variables and functions are ignored
+    $expressionLanguage->lint('unknown_var + unknown_function()', [], Parser::IGNORE_UNKNOWN_VARIABLES | Parser::IGNORE_UNKNOWN_FUNCTIONS);
 
 .. versionadded:: 7.1
 

From 694cd4c081b693324a303930241ac04beca488d1 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 6 Dec 2024 09:08:20 +0100
Subject: [PATCH 428/747] Minor tweaks

---
 components/expression_language.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/components/expression_language.rst b/components/expression_language.rst
index 7dacf581b14..b0dd10b0f42 100644
--- a/components/expression_language.rst
+++ b/components/expression_language.rst
@@ -107,7 +107,7 @@ if the expression is not valid::
     $expressionLanguage->lint('1 + 2', []); // doesn't throw anything
 
     $expressionLanguage->lint('1 + a', []);
-    // Throw SyntaxError Exception
+    // throws a SyntaxError exception:
     // "Variable "a" is not valid around position 5 for expression `1 + a`."
 
 The behavior of these methods can be configured with some flags defined in the
@@ -125,7 +125,7 @@ This is how you can use these flags::
 
     $expressionLanguage = new ExpressionLanguage();
 
-    // Does not throw a SyntaxError because the unknown variables and functions are ignored
+    // does not throw a SyntaxError because the unknown variables and functions are ignored
     $expressionLanguage->lint('unknown_var + unknown_function()', [], Parser::IGNORE_UNKNOWN_VARIABLES | Parser::IGNORE_UNKNOWN_FUNCTIONS);
 
 .. versionadded:: 7.1

From c14a4e733e4ba53e7fc5746356465d8924b22f5c Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Sat, 7 Dec 2024 10:48:52 +0100
Subject: [PATCH 429/747] [AssetMapper] Document the feature that precompresses
 assets

---
 frontend/asset_mapper.rst | 61 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 60 insertions(+), 1 deletion(-)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index f519c7c6109..708de32979f 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -656,7 +656,9 @@ which will automatically do most of these things for you:
 - **Compress your assets**: Your web server should compress (e.g. using gzip)
   your assets (JavaScript, CSS, images) before sending them to the browser. This
   is automatically enabled in Caddy and can be activated in Nginx and Apache.
-  In Cloudflare, assets are compressed by default.
+  In Cloudflare, assets are compressed by default. AssetMapper also supports
+  :ref:`precompressing your web assets <performance-precompressing>` to further
+  improve performance.
 
 - **Set long-lived cache expiry**: Your web server should set a long-lived
   ``Cache-Control`` HTTP header on your assets. Because the AssetMapper component includes a version
@@ -704,6 +706,57 @@ even though it hasn't yet seen the ``import`` statement for them.
 Additionally, if the :doc:`WebLink Component </web_link>` is available in your application,
 Symfony will add a ``Link`` header in the response to preload the CSS files.
 
+.. _performance-precompressing:
+
+Pre-Compressing Assets
+----------------------
+
+Although most servers (Caddy, Nginx, Apache, FrankenPHP) and services like Cloudflare
+provide asset compression features, AssetMapper also allows you to compress all
+your assets before serving them.
+
+This improves performance because you can compress assets using the highest (and
+slowest) compression ratios beforehand and provide those compressed assets to the
+server, which then returns them to the client without wasting CPU resources on
+compression.
+
+AssetMapper supports  `Brotli`_, `Zstandard`_ and  `gzip`_ compression formats.
+Before using any of them, the server that pre-compresses assets must have
+installed the following PHP extensions or CLI commands:
+
+* Brotli: ``brotli`` CLI command; `brotli PHP extension`_;
+* Zstandard: ``zstd`` CLI command; `zstd PHP extension`_;
+* gzip: ``gzip`` CLI command; `zlib PHP extension`_.
+
+Then, update your AssetMapper configuration to define which compression to use
+and which file extensions should be compressed:
+
+.. code-block:: yaml
+
+    # config/packages/asset_mapper.yaml
+    framework:
+        asset_mapper:
+            # ...
+
+            precompress:
+                format: 'zstandard'
+                # if you don't define the following option, AssetMapper will compress all
+                # the extensions considered safe (css, js, json, svg, xml, ttf, otf, wasm, etc.)
+                extensions: ['css', 'js', 'json', 'svg', 'xml']
+
+Now, when running the ``asset-map:compile`` command, all matching files will be
+compressed in the configured format and at the highest compression level. The
+compressed files are created with the same name as the original but with the
+``.br``, ``.zst``, or ``.gz`` extension appended. Web servers that support asset
+precompression will use the compressed assets automatically, so there's nothing
+else to configure in your server.
+
+.. tip::
+
+    AssetMapper provides an ``assets:compress`` CLI command and a service called
+    ``asset_mapper.compressor`` that you can use anywhere in your application to
+    compress any kind of files (e.g. files uploaded by users to your application).
+
 Frequently Asked Questions
 --------------------------
 
@@ -1195,3 +1248,9 @@ command as part of your CI to be warned anytime a new vulnerability is found.
 .. _strict-dynamic: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#strict-dynamic
 .. _kocal/biome-js-bundle: https://github.com/Kocal/BiomeJsBundle
 .. _`SensioLabs Minify Bundle`: https://github.com/sensiolabs/minify-bundle
+.. _`Brotli`: https://en.wikipedia.org/wiki/Brotli
+.. _`Zstandard`: https://en.wikipedia.org/wiki/Zstd
+.. _`gzip`: https://en.wikipedia.org/wiki/Gzip
+.. _`brotli PHP extension`: https://pecl.php.net/package/brotli
+.. _`zstd PHP extension`: https://pecl.php.net/package/zstd
+.. _`zlib PHP extension`: https://www.php.net/manual/en/book.zlib.php

From 85ceb630c6ec51f55f185847dc191d5dad2e712b Mon Sep 17 00:00:00 2001
From: Timo Bakx <github@timobakx.dev>
Date: Sat, 7 Dec 2024 12:13:49 +0100
Subject: [PATCH 430/747] Replaced `caution` directive by `warning`

Fixes #20371
---
 components/type_info.rst | 2 +-
 doctrine.rst             | 2 +-
 mailer.rst               | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index 30ae11aa222..2fd64b9bc5d 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -11,7 +11,7 @@ This component provides:
 * A way to get types from PHP elements such as properties, method arguments,
   return types, and raw strings.
 
-.. caution::
+.. warning::
 
     This component is :doc:`experimental </contributing/code/experimental>` and
     could be changed at any time without prior notice.
diff --git a/doctrine.rst b/doctrine.rst
index f9c1d153d82..171f8a3348a 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -320,7 +320,7 @@ before, execute your migrations:
 
     $ php bin/console doctrine:migrations:migrate
 
-.. caution::
+.. warning::
 
     If you are using an SQLite database, you'll see the following error:
     *PDOException: SQLSTATE[HY000]: General error: 1 Cannot add a NOT NULL
diff --git a/mailer.rst b/mailer.rst
index 0d3e296ee77..06feb1e5c29 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -361,7 +361,7 @@ setting the ``auto_tls`` option to ``false`` in the DSN::
 
     $dsn = 'smtp://user:pass@10.0.0.25?auto_tls=false';
 
-.. caution::
+.. warning::
 
     It's not recommended to disable TLS while connecting to an SMTP server over
     the Internet, but it can be useful when both the application and the SMTP

From 0a3fb8d716fd0adf21d56762821ce7b19f71b90b Mon Sep 17 00:00:00 2001
From: Timo Bakx <github@timobakx.dev>
Date: Sat, 7 Dec 2024 12:19:15 +0100
Subject: [PATCH 431/747] Replaced `caution` directive by `warning`

Fixes #20371
---
 reference/forms/types/options/choice_lazy.rst.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/forms/types/options/choice_lazy.rst.inc b/reference/forms/types/options/choice_lazy.rst.inc
index bdcbf178406..08fbe953e41 100644
--- a/reference/forms/types/options/choice_lazy.rst.inc
+++ b/reference/forms/types/options/choice_lazy.rst.inc
@@ -24,7 +24,7 @@ will only load and render the choices that are preset as default values or
 submitted. This defers the loading of the full list of choices, helping to
 improve your form's performance.
 
-.. caution::
+.. warning::
 
     Keep in mind that when using ``choice_lazy``, you are responsible for
     providing the user interface for selecting choices, typically through a

From b53029a64602d1cde5aa704ae1145532ee875bf3 Mon Sep 17 00:00:00 2001
From: Matthias Schmidt <matthias@mttsch.dev>
Date: Mon, 22 Apr 2024 18:56:41 +0200
Subject: [PATCH 432/747] [Serializer] Add class/format/context to
 NameConverterInterface

Fix #19683
---
 serializer/custom_name_converter.rst | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/serializer/custom_name_converter.rst b/serializer/custom_name_converter.rst
index 82247134217..d0ed45bdc0a 100644
--- a/serializer/custom_name_converter.rst
+++ b/serializer/custom_name_converter.rst
@@ -30,19 +30,26 @@ A custom name converter can handle such cases::
 
     class OrgPrefixNameConverter implements NameConverterInterface
     {
-        public function normalize(string $propertyName): string
+        public function normalize(string $propertyName, string $class = null, ?string $format = null, array $context = []): string
         {
             // during normalization, add the prefix
             return 'org_'.$propertyName;
         }
 
-        public function denormalize(string $propertyName): string
+        public function denormalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
         {
             // remove the 'org_' prefix on denormalizing
             return str_starts_with($propertyName, 'org_') ? substr($propertyName, 4) : $propertyName;
         }
     }
 
+.. versionadded:: 7.1
+
+    Accessing the current class name, format and context via
+    :method:`Symfony\\Component\\Serializer\\NameConverter\\NameConverterInterface::normalize`
+    and :method:`Symfony\\Component\\Serializer\\NameConverter\\NameConverterInterface::denormalize`
+    was introduced in Symfony 7.1.
+
 .. note::
 
     You can also implement

From d159a4a03e036d7a4664fd02fe07ddf1480850a4 Mon Sep 17 00:00:00 2001
From: Nicolas Appriou <n.appriou@alsim.com>
Date: Wed, 1 Feb 2023 12:55:17 +0100
Subject: [PATCH 433/747] [HttpFoundation] Update http response test constraint
 signature

---
 testing.rst | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/testing.rst b/testing.rst
index 2e681c70543..30c0e87ab77 100644
--- a/testing.rst
+++ b/testing.rst
@@ -961,11 +961,11 @@ However, Symfony provides useful shortcut methods for the most common cases:
 Response Assertions
 ...................
 
-``assertResponseIsSuccessful(string $message = '')``
+``assertResponseIsSuccessful(string $message = '', bool $verbose = true)``
     Asserts that the response was successful (HTTP status is 2xx).
-``assertResponseStatusCodeSame(int $expectedCode, string $message = '')``
+``assertResponseStatusCodeSame(int $expectedCode, string $message = '', bool $verbose = true)``
     Asserts a specific HTTP status code.
-``assertResponseRedirects(?string $expectedLocation = null, ?int $expectedCode = null, string $message = '')``
+``assertResponseRedirects(?string $expectedLocation = null, ?int $expectedCode = null, string $message = '', bool $verbose = true)``
     Asserts the response is a redirect response (optionally, you can check
     the target location and status code). The excepted location can be either
     an absolute or a relative path.
@@ -983,9 +983,13 @@ Response Assertions
     Asserts the response format returned by the
     :method:`Symfony\\Component\\HttpFoundation\\Response::getFormat` method
     is the same as the expected value.
-``assertResponseIsUnprocessable(string $message = '')``
+``assertResponseIsUnprocessable(string $message = '', bool $verbose = true)``
     Asserts the response is unprocessable (HTTP status is 422)
 
+.. versionadded:: 7.1
+
+    The ``$verbose`` parameters were introduced in Symfony 7.1.
+
 Request Assertions
 ..................
 

From 1d690fc9714cf2ebb6506c3656e6aa6e7909c33a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= <kevin@dunglas.fr>
Date: Sat, 7 Dec 2024 17:04:18 +0100
Subject: [PATCH 434/747] [AssetMapper] mention Zopfli pre-compression and add
 config for web servers

---
 frontend/asset_mapper.rst | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index b55803e157f..e83da5aa42b 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -726,7 +726,7 @@ installed the following PHP extensions or CLI commands:
 
 * Brotli: ``brotli`` CLI command; `brotli PHP extension`_;
 * Zstandard: ``zstd`` CLI command; `zstd PHP extension`_;
-* gzip: ``gzip`` CLI command; `zlib PHP extension`_.
+* gzip: ``zopfli`` (better) or ``gzip`` CLI command; `zlib PHP extension`_.
 
 Then, update your AssetMapper configuration to define which compression to use
 and which file extensions should be compressed:
@@ -751,6 +751,27 @@ compressed files are created with the same name as the original but with the
 precompression will use the compressed assets automatically, so there's nothing
 else to configure in your server.
 
+Finally, you need to configure your web server to serve the precompressed assets
+instead of the original ones:
+
+.. configuration-block::
+
+    .. code-block:: caddy
+
+        file_server {
+            precompressed br zstd gzip
+        }
+
+    .. code-block:: nginx
+
+        gzip_static on;
+
+        # Requires https://github.com/google/ngx_brotli
+        brotli_static on;
+
+        # Requires https://github.com/tokers/zstd-nginx-module
+        zstd_static on;
+
 .. tip::
 
     AssetMapper provides an ``assets:compress`` CLI command and a service called

From 405f95ef8844382504372d0dc85178505d7cdfed Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 10 Dec 2024 15:51:38 +0100
Subject: [PATCH 435/747] Minor reword

---
 components/type_info.rst | 64 ++++++++++++++++++++++------------------
 1 file changed, 35 insertions(+), 29 deletions(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index 18556e02972..734ac4140ba 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -43,9 +43,9 @@ to the :class:`Symfony\\Component\\TypeInfo\\Type` static methods as following::
 Resolvers
 ~~~~~~~~~
 
-The second way of using the component is to use ``TypeInfo`` to resolve a type
-based on reflection or a simple string, this is aimed towards libraries that wants to
-describe a class or anything that has a type easily::
+The second way to use the component is by using ``TypeInfo`` to resolve a type
+based on reflection or a simple string. This approach is designed for libraries
+that need a simple way to describe a class or anything with a type::
 
     use Symfony\Component\TypeInfo\Type;
     use Symfony\Component\TypeInfo\TypeResolver\TypeResolver;
@@ -82,13 +82,15 @@ Each of these calls will return you a ``Type`` instance that corresponds to the
 static method used. You can also resolve types from a string (as shown in the
 ``bool`` parameter of the previous example)
 
-PHPDoc parsing
+PHPDoc Parsing
 ~~~~~~~~~~~~~~
 
-But most times you won't have clean typed properties or you want a more precise type
-thank to advanced PHPDoc, to do that you would want a string resolver based on that PHPDoc.
-First you will require ``phpstan/phpdoc-parser`` package from composer to support string
-revolving. Then you would do as following::
+In many cases, you may not have cleanly typed properties or may need more precise
+type definitions provided by advanced PHPDoc. To achieve this, you can use a string
+resolver based on the PHPDoc annotations.
+
+First, run the command ``composer require phpstan/phpdoc-parser`` to install the
+PHP package required for string resolving. Then, follow these steps::
 
     use Symfony\Component\TypeInfo\TypeResolver\TypeResolver;
 
@@ -106,35 +108,40 @@ revolving. Then you would do as following::
     $typeResolver->resolve(new \ReflectionProperty(Dummy::class, 'id')); // returns an "int" Type
     $typeResolver->resolve(new \ReflectionProperty(Dummy::class, 'id')); // returns a collection with "int" as key and "string" as values Type
 
-Advanced usages
+Advanced Usages
 ~~~~~~~~~~~~~~~
 
-There is many methods to manipulate and check types depending on your needs within the TypeInfo components.
+The TypeInfo component provides various methods to manipulate and check types,
+depending on your needs.
 
-If you need a check a simple Type::
+Checking a **simple type**::
 
-    // You need to check if a Type
-    $type = Type::int(); // with a simple int type
-    // You can check if a given type comply with a given identifier
-    $type->isIdentifiedBy(TypeIdentifier::INT); // true
+    // define a simple integer type
+    $type = Type::int();
+    // check if the type matches a specific identifier
+    $type->isIdentifiedBy(TypeIdentifier::INT);    // true
     $type->isIdentifiedBy(TypeIdentifier::STRING); // false
 
-    $type = Type::union(Type::string(), Type::int()); // with an union of int and string types
-    // You can now see that the second check will pass to true since we have an union with a string type
-    $type->isIdentifiedBy(TypeIdentifier::INT); // true
+    // define a union type (equivalent to PHP's int|string)
+    $type = Type::union(Type::string(), Type::int());
+    // now the second check is true because the union type contains the string type
+    $type->isIdentifiedBy(TypeIdentifier::INT);    // true
     $type->isIdentifiedBy(TypeIdentifier::STRING); // true
 
     class DummyParent {}
     class Dummy extends DummyParent implements DummyInterface {}
-    $type = Type::object(Dummy::class); // with an object Type
-    // You can check is the Type is an object, or even if it's a given class
+
+    // define an object type
+    $type = Type::object(Dummy::class);
+
+    // check if the type is an object or matches a specific class
     $type->isIdentifiedBy(TypeIdentifier::OBJECT); // true
-    $type->isIdentifiedBy(Dummy::class); // true
-    // Or inherits/implements something
-    $type->isIdentifiedBy(DummyParent::class); // true
-    $type->isIdentifiedBy(DummyInterface::class); // true
+    $type->isIdentifiedBy(Dummy::class);           // true
+    // check if it inherits/implements something
+    $type->isIdentifiedBy(DummyParent::class);     // true
+    $type->isIdentifiedBy(DummyInterface::class);  // true
 
-Sometimes you want to check for more than one thing at a time so a callable may be better to check everything::
+Using callables for **complex checks**:
 
     class Foo
     {
@@ -150,8 +157,7 @@ Sometimes you want to check for more than one thing at a time so a callable may
     $stringType = $resolver->resolve($reflClass->getProperty('string'));
     $floatType = $resolver->resolve($reflClass->getProperty('float'));
 
-    // your callable to check whatever you need
-    // here we want to validate a given type is a non nullable number
+    // define a callable to validate non-nullable number types
     $isNonNullableNumber = function (Type $type): bool {
         if ($type->isNullable()) {
             return false;
@@ -165,5 +171,5 @@ Sometimes you want to check for more than one thing at a time so a callable may
     };
 
     $integerType->isSatisfiedBy($isNonNullableNumber); // true
-    $stringType->isSatisfiedBy($isNonNullableNumber); // false
-    $floatType->isSatisfiedBy($isNonNullableNumber); // false
+    $stringType->isSatisfiedBy($isNonNullableNumber);  // false
+    $floatType->isSatisfiedBy($isNonNullableNumber);   // false

From f87bbdf690f629b3096a1f8d0848f471d5e966ed Mon Sep 17 00:00:00 2001
From: Mathias Arlaud <mathias.arlaud@gmail.com>
Date: Wed, 11 Dec 2024 10:38:18 +0100
Subject: [PATCH 436/747] [HttpFoundation] Add StreamedResponse string iterable
 documentation

---
 components/http_foundation.rst | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/components/http_foundation.rst b/components/http_foundation.rst
index c91ec5ced8f..8db6cd27f68 100644
--- a/components/http_foundation.rst
+++ b/components/http_foundation.rst
@@ -681,8 +681,19 @@ Streaming a Response
 ~~~~~~~~~~~~~~~~~~~~
 
 The :class:`Symfony\\Component\\HttpFoundation\\StreamedResponse` class allows
-you to stream the Response back to the client. The response content is
-represented by a PHP callable instead of a string::
+you to stream the Response back to the client. The response content can be
+represented by a string iterable::
+
+    use Symfony\Component\HttpFoundation\StreamedResponse;
+
+    $chunks = ['Hello', ' World'];
+
+    $response = new StreamedResponse();
+    $response->setChunks($chunks);
+    $response->send();
+
+For most complex use cases, the response content can be instead represented by
+a PHP callable::
 
     use Symfony\Component\HttpFoundation\StreamedResponse;
 
@@ -710,6 +721,10 @@ represented by a PHP callable instead of a string::
         // disables FastCGI buffering in nginx only for this response
         $response->headers->set('X-Accel-Buffering', 'no');
 
+.. versionadded:: 7.3
+
+    Support for using string iterables was introduced in Symfony 7.3.
+
 Streaming a JSON Response
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 

From b66e743657a527d4c14e3e4a1330893c6956cc4d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20L=C3=A9v=C3=AAque?= <sebastien@leveque.eu>
Date: Wed, 11 Dec 2024 17:11:32 +0100
Subject: [PATCH 437/747] [Console] Add support of millisecondes for formatTime

---
 components/console/helpers/formatterhelper.rst | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/components/console/helpers/formatterhelper.rst b/components/console/helpers/formatterhelper.rst
index 3cb87c4c307..bff0c82c90f 100644
--- a/components/console/helpers/formatterhelper.rst
+++ b/components/console/helpers/formatterhelper.rst
@@ -129,10 +129,12 @@ Sometimes you want to format seconds to time. This is possible with the
 The first argument is the seconds to format and the second argument is the
 precision (default ``1``) of the result::
 
-    Helper::formatTime(42);        // 42 secs
-    Helper::formatTime(125);       // 2 mins
-    Helper::formatTime(125, 2);    // 2 mins, 5 secs
-    Helper::formatTime(172799, 4); // 1 day, 23 hrs, 59 mins, 59 secs
+    Helper::formatTime(0.001);         // 1 ms
+    Helper::formatTime(42);            // 42 s
+    Helper::formatTime(125);           // 2 min
+    Helper::formatTime(125, 2);        // 2 min, 5 s
+    Helper::formatTime(172799, 4);     // 1 d, 23 h, 59 min, 59 s
+    Helper::formatTime(172799.056, 5); // 1 d, 23 h, 59 min, 59 s, 56 ms
 
 Formatting Memory
 -----------------

From bf5dd100d61c54ed6e4ed729198d2d04a64940a0 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 12 Dec 2024 10:56:45 +0100
Subject: [PATCH 438/747] Add the versionadded directive

---
 components/console/helpers/formatterhelper.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/components/console/helpers/formatterhelper.rst b/components/console/helpers/formatterhelper.rst
index bff0c82c90f..d2b19915a3a 100644
--- a/components/console/helpers/formatterhelper.rst
+++ b/components/console/helpers/formatterhelper.rst
@@ -136,6 +136,10 @@ precision (default ``1``) of the result::
     Helper::formatTime(172799, 4);     // 1 d, 23 h, 59 min, 59 s
     Helper::formatTime(172799.056, 5); // 1 d, 23 h, 59 min, 59 s, 56 ms
 
+.. versionadded:: 7.3
+
+    Support for formatting up to milliseconds was introduced in Symfony 7.3.
+
 Formatting Memory
 -----------------
 

From eb5ffa691cc0239d89c72d9ca74897b2e85b23fc Mon Sep 17 00:00:00 2001
From: Baptiste Leduc <baptiste.leduc@gmail.com>
Date: Thu, 12 Dec 2024 11:48:47 +0100
Subject: [PATCH 439/747] Fix PHP block in TypeInfo documentation

---
 components/type_info.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index 734ac4140ba..e7062c5f249 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -141,7 +141,7 @@ Checking a **simple type**::
     $type->isIdentifiedBy(DummyParent::class);     // true
     $type->isIdentifiedBy(DummyInterface::class);  // true
 
-Using callables for **complex checks**:
+Using callables for **complex checks**::
 
     class Foo
     {

From 3e4bcf17aae617ddf5295e53b95bd505b1a1d509 Mon Sep 17 00:00:00 2001
From: Baptiste Leduc <baptiste.leduc@gmail.com>
Date: Thu, 12 Dec 2024 11:48:47 +0100
Subject: [PATCH 440/747] Fix PHP block in TypeInfo documentation

---
 components/type_info.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index 734ac4140ba..e7062c5f249 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -141,7 +141,7 @@ Checking a **simple type**::
     $type->isIdentifiedBy(DummyParent::class);     // true
     $type->isIdentifiedBy(DummyInterface::class);  // true
 
-Using callables for **complex checks**:
+Using callables for **complex checks**::
 
     class Foo
     {

From b0f09c62f9bfbd876ea954b1a302491fb05473e7 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Tue, 17 Dec 2024 09:34:01 +0100
Subject: [PATCH 441/747] use ? before nullable single type declaration

---
 serializer/custom_name_converter.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/serializer/custom_name_converter.rst b/serializer/custom_name_converter.rst
index d0ed45bdc0a..49dafb02cc4 100644
--- a/serializer/custom_name_converter.rst
+++ b/serializer/custom_name_converter.rst
@@ -30,7 +30,7 @@ A custom name converter can handle such cases::
 
     class OrgPrefixNameConverter implements NameConverterInterface
     {
-        public function normalize(string $propertyName, string $class = null, ?string $format = null, array $context = []): string
+        public function normalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
         {
             // during normalization, add the prefix
             return 'org_'.$propertyName;

From 2fdd0dbfd61d9bd93d679c8febedcddca40d5e3a Mon Sep 17 00:00:00 2001
From: Felix Eymonot <felix.eymonot@gmail.com>
Date: Tue, 17 Dec 2024 12:19:23 +0100
Subject: [PATCH 442/747] docs(controller): add docs for key option in
 MapQueryString

---
 controller.rst | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/controller.rst b/controller.rst
index c11615d93aa..5da85057bbe 100644
--- a/controller.rst
+++ b/controller.rst
@@ -443,6 +443,27 @@ HTTP status to return if the validation fails::
 
 The default status code returned if the validation fails is 404.
 
+If you want to map your object to a nested array in your query with a specific key,
+you can use the ``key`` option in your :class:`Symfony\\Component\\HttpKernel\\Attribute\\MapQueryString`
+attribute::
+
+    use App\Model\SearchDto;
+    use Symfony\Component\HttpFoundation\Response;
+    use Symfony\Component\HttpKernel\Attribute\MapQueryString;
+
+    // ...
+
+    public function dashboard(
+        #[MapQueryString(key: 'search')] SearchDto $searchDto
+    ): Response
+    {
+        // ...
+    }
+
+.. versionadded:: 7.3
+
+    The ``key`` option of ``#[MapQueryString]`` was introduced in Symfony 7.3.
+
 If you need a valid DTO even when the request query string is empty, set a
 default value for your controller arguments::
 

From 8aeceab63ce821c69bb182377ad1c3c0b54bf17e Mon Sep 17 00:00:00 2001
From: Christophe Coevoet <stof@notk.org>
Date: Tue, 17 Dec 2024 13:06:15 +0100
Subject: [PATCH 443/747] Fix the configuration for custom password strength
 estimator

---
 reference/constraints/PasswordStrength.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/reference/constraints/PasswordStrength.rst b/reference/constraints/PasswordStrength.rst
index 671b5f495ef..60125a763a1 100644
--- a/reference/constraints/PasswordStrength.rst
+++ b/reference/constraints/PasswordStrength.rst
@@ -178,7 +178,7 @@ service to use your own estimator:
                 class: App\Validator\CustomPasswordStrengthEstimator
 
             Symfony\Component\Validator\Constraints\PasswordStrengthValidator:
-                arguments: [!service_closure '@custom_password_strength_estimator']
+                arguments: [!closure '@custom_password_strength_estimator']
 
     .. code-block:: xml
 
@@ -192,7 +192,7 @@ service to use your own estimator:
                 <service id="custom_password_strength_estimator" class="App\Validator\CustomPasswordStrengthEstimator"/>
 
                 <service id="Symfony\Component\Validator\Constraints\PasswordStrengthValidator">
-                    <argument type="service_closure" id="custom_password_strength_estimator"/>
+                    <argument type="closure" id="custom_password_strength_estimator"/>
                 </service>
             </services>
         </container>
@@ -210,5 +210,5 @@ service to use your own estimator:
             $services->set('custom_password_strength_estimator', CustomPasswordStrengthEstimator::class);
 
             $services->set(PasswordStrengthValidator::class)
-                ->args([service_closure('custom_password_strength_estimator')]);
+                ->args([closure('custom_password_strength_estimator')]);
         };

From c196b447547b28048a9f1d5849f6964e982933ad Mon Sep 17 00:00:00 2001
From: Nate Wiebe <nate@northern.co>
Date: Thu, 9 Mar 2023 09:10:30 -0500
Subject: [PATCH 444/747] Add tip for using new isGrantedForUser() function

---
 security.rst | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/security.rst b/security.rst
index c8dfc8d6233..5da16121b30 100644
--- a/security.rst
+++ b/security.rst
@@ -2585,6 +2585,18 @@ want to include extra details only for users that have a ``ROLE_SALES_ADMIN`` ro
           // ...
       }
 
+.. tip::
+
+    Using ``isGranted()`` checks authorization against the currently logged in user. If you need to check
+    against a user that is not the one logged in or if checking authorization when the user session is not
+    available in a CLI context (example: message queue, cronjob) ``isGrantedForUser()`` can be used to set the
+    target user explicitly.
+
+    .. versionadded:: 7.3
+
+        The :method:`Symfony\\Bundle\\SecurityBundle\\Security::isGrantedForUser`
+        method was introduced in Symfony 7.3.
+
 If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`,
 Symfony will automatically pass the ``security.helper`` to your service
 thanks to autowiring and the ``Security`` type-hint.

From f10c7e9f81e4db9cba84d03027ca7eccf0a9e31f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20PLANUS?=
 <48881747+leo29plns@users.noreply.github.com>
Date: Thu, 19 Dec 2024 08:06:37 +0100
Subject: [PATCH 445/747] Update 7.2.x-dev to 7.2.x

---
 setup.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/setup.rst b/setup.rst
index 1d7081e93b7..853b53f2400 100644
--- a/setup.rst
+++ b/setup.rst
@@ -48,10 +48,10 @@ application:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ symfony new my_project_directory --version="7.2.x-dev" --webapp
+    $ symfony new my_project_directory --version="7.2.x" --webapp
 
     # run this if you are building a microservice, console application or API
-    $ symfony new my_project_directory --version="7.2.x-dev"
+    $ symfony new my_project_directory --version="7.2.x"
 
 The only difference between these two commands is the number of packages
 installed by default. The ``--webapp`` option installs extra packages to give
@@ -63,12 +63,12 @@ Symfony application using Composer:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ composer create-project symfony/skeleton:"7.2.x-dev" my_project_directory
+    $ composer create-project symfony/skeleton:"7.2.x" my_project_directory
     $ cd my_project_directory
     $ composer require webapp
 
     # run this if you are building a microservice, console application or API
-    $ composer create-project symfony/skeleton:"7.2.x-dev" my_project_directory
+    $ composer create-project symfony/skeleton:"7.2.x" my_project_directory
 
 No matter which command you run to create the Symfony application. All of them
 will create a new ``my_project_directory/`` directory, download some dependencies

From ccdeed257e1e882374a185b18437933694b94bb7 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 19 Dec 2024 17:47:14 +0100
Subject: [PATCH 446/747] Minor tweak

---
 controller.rst | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/controller.rst b/controller.rst
index 5da85057bbe..026e76ed0a6 100644
--- a/controller.rst
+++ b/controller.rst
@@ -443,9 +443,8 @@ HTTP status to return if the validation fails::
 
 The default status code returned if the validation fails is 404.
 
-If you want to map your object to a nested array in your query with a specific key,
-you can use the ``key`` option in your :class:`Symfony\\Component\\HttpKernel\\Attribute\\MapQueryString`
-attribute::
+If you want to map your object to a nested array in your query using a specific key,
+set the ``key`` option in the ``#[MapQueryString]`` attribute::
 
     use App\Model\SearchDto;
     use Symfony\Component\HttpFoundation\Response;

From d99915066523753285953b349f1a9782cc353fd1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20Andr=C3=A9?= <smn.andre@gmail.com>
Date: Sun, 22 Dec 2024 14:40:09 +0100
Subject: [PATCH 447/747] [AssetMapper] Update hash examples

Since 7.2, hash are shorter. This PR updates the various hashes in code examples, to illustrate more precisely what a user will see on its local install / code.
---
 frontend/asset_mapper.rst | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index decc7827e0d..95b656f043d 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -12,7 +12,7 @@ The component has two main features:
 * :ref:`Mapping & Versioning Assets <mapping-assets>`: All files inside of ``assets/``
   are made available publicly and **versioned**. You can reference the file
   ``assets/images/product.jpg`` in a Twig template with ``{{ asset('images/product.jpg') }}``.
-  The final URL will include a version hash, like ``/assets/images/product-3c16d9220694c0e56d8648f25e6035e9.jpg``.
+  The final URL will include a version hash, like ``/assets/images/product-3c16d92m.jpg``.
 
 * :ref:`Importmaps <importmaps-javascript>`: A native browser feature that makes it easier
   to use the JavaScript ``import`` statement (e.g. ``import { Modal } from 'bootstrap'``)
@@ -70,7 +70,7 @@ The path - ``images/duck.png`` - is relative to your mapped directory (``assets/
 This is known as the **logical path** to your asset.
 
 If you look at the HTML in your page, the URL will be something
-like: ``/assets/images/duck-3c16d9220694c0e56d8648f25e6035e9.png``. If you change
+like: ``/assets/images/duck-3c16d92m.png``. If you change
 the file, the version part of the URL will also change automatically.
 
 .. _asset-mapper-compile-assets:
@@ -78,7 +78,7 @@ the file, the version part of the URL will also change automatically.
 Serving Assets in dev vs prod
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-In the ``dev`` environment, the URL ``/assets/images/duck-3c16d9220694c0e56d8648f25e6035e9.png``
+In the ``dev`` environment, the URL ``/assets/images/duck-3c16d92m.png``
 is handled and returned by your Symfony app.
 
 For the ``prod`` environment, before deploy, you should run:
@@ -283,9 +283,9 @@ outputs an `importmap`_:
 
     <script type="importmap">{
         "imports": {
-            "app": "/assets/app-4e986c1a2318dd050b1d47db8d856278.js",
-            "/assets/duck.js": "/assets/duck-1b7a64b3b3d31219c262cf72521a5267.js",
-            "bootstrap": "/assets/vendor/bootstrap/bootstrap.index-f0935445d9c6022100863214b519a1f2.js"
+            "app": "/assets/app-4e986c1a.js",
+            "/assets/duck.js": "/assets/duck-1b7a64b3.js",
+            "bootstrap": "/assets/vendor/bootstrap/bootstrap.index-f093544d.js"
         }
     }</script>
 
@@ -342,8 +342,8 @@ The ``importmap()`` function also outputs a set of "preloads":
 
 .. code-block:: html
 
-    <link rel="modulepreload" href="/assets/app-4e986c1a2318dd050b1d47db8d856278.js">
-    <link rel="modulepreload" href="/assets/duck-1b7a64b3b3d31219c262cf72521a5267.js">
+    <link rel="modulepreload" href="/assets/app-4e986c1a.js">
+    <link rel="modulepreload" href="/assets/duck-1b7a64b3.js">
 
 This is a performance optimization and you can learn more about below
 in :ref:`Performance: Add Preloading <performance-preloading>`.
@@ -494,9 +494,9 @@ for ``duck.png``:
 
 .. code-block:: css
 
-    /* public/assets/styles/app-3c16d9220694c0e56d8648f25e6035e9.css */
+    /* public/assets/styles/app-3c16d92m.css */
     .quack {
-        background-image: url('../images/duck-3c16d9220694c0e56d8648f25e6035e9.png');
+        background-image: url('../images/duck-3c16d92m.png');
     }
 
 .. _asset-mapper-tailwind:
@@ -573,7 +573,7 @@ Sometimes a JavaScript file you're importing (e.g. ``import './duck.js'``),
 or a CSS/image file you're referencing won't be found, and you'll see a 404
 error in your browser's console. You'll also notice that the 404 URL is missing
 the version hash in the filename (e.g. a 404 to ``/assets/duck.js`` instead of
-a path like ``/assets/duck.1b7a64b3b3d31219c262cf72521a5267.js``).
+a path like ``/assets/duck-1b7a64b3.js``).
 
 This is usually because the path is wrong. If you're referencing the file
 directly in a Twig template:
@@ -848,7 +848,7 @@ be versioned! It will output something like:
 
 .. code-block:: html+twig
 
-    <link rel="stylesheet" href="/assets/bundles/babdevpagerfanta/css/pagerfanta-ea64fc9c55f8394e696554f8aeb81a8e.css">
+    <link rel="stylesheet" href="/assets/bundles/babdevpagerfanta/css/pagerfanta-ea64fc9c.css">
 
 Overriding 3rd-Party Assets
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

From 47e65dfb47d70815d3bbe8e7c809c421b2ad4ec9 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 26 Dec 2024 11:17:56 +0100
Subject: [PATCH 448/747] Update the Symfony version to install in 7.3 branch

---
 setup.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/setup.rst b/setup.rst
index 853b53f2400..b269da2c476 100644
--- a/setup.rst
+++ b/setup.rst
@@ -48,10 +48,10 @@ application:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ symfony new my_project_directory --version="7.2.x" --webapp
+    $ symfony new my_project_directory --version="7.3.x-dev" --webapp
 
     # run this if you are building a microservice, console application or API
-    $ symfony new my_project_directory --version="7.2.x"
+    $ symfony new my_project_directory --version="7.3.x-dev"
 
 The only difference between these two commands is the number of packages
 installed by default. The ``--webapp`` option installs extra packages to give
@@ -63,12 +63,12 @@ Symfony application using Composer:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ composer create-project symfony/skeleton:"7.2.x" my_project_directory
+    $ composer create-project symfony/skeleton:"7.3.x-dev" my_project_directory
     $ cd my_project_directory
     $ composer require webapp
 
     # run this if you are building a microservice, console application or API
-    $ composer create-project symfony/skeleton:"7.2.x" my_project_directory
+    $ composer create-project symfony/skeleton:"7.3.x-dev" my_project_directory
 
 No matter which command you run to create the Symfony application. All of them
 will create a new ``my_project_directory/`` directory, download some dependencies

From 04790be521b670ddffbee654c55da3bc165dfd55 Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Mon, 30 Dec 2024 08:38:13 +0100
Subject: [PATCH 449/747] [Validator] Validate SVG ratio in Image validator

---
 reference/constraints/Image.rst | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/reference/constraints/Image.rst b/reference/constraints/Image.rst
index 48dc1d5e0ed..23fbe5a157a 100644
--- a/reference/constraints/Image.rst
+++ b/reference/constraints/Image.rst
@@ -210,6 +210,10 @@ add several other options.
 
 If this option is false, the image cannot be landscape oriented.
 
+.. versionadded:: 7.3
+
+    The ``allowLandscape`` option support for SVG files was introduced in Symfony 7.3.
+
 ``allowLandscapeMessage``
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -234,6 +238,10 @@ Parameter         Description
 
 If this option is false, the image cannot be portrait oriented.
 
+.. versionadded:: 7.3
+
+    The ``allowPortrait`` option support for SVG files was introduced in Symfony 7.3.
+
 ``allowPortraitMessage``
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -260,6 +268,10 @@ If this option is false, the image cannot be a square. If you want to force
 a square image, then leave this option as its default ``true`` value
 and set `allowLandscape`_ and `allowPortrait`_ both to ``false``.
 
+.. versionadded:: 7.3
+
+    The ``allowSquare`` option support for SVG files was introduced in Symfony 7.3.
+
 ``allowSquareMessage``
 ~~~~~~~~~~~~~~~~~~~~~~
 
@@ -358,6 +370,10 @@ Parameter             Description
 If set, the aspect ratio (``width / height``) of the image file must be less
 than or equal to this value.
 
+.. versionadded:: 7.3
+
+    The ``maxRatio`` option support for SVG files was introduced in Symfony 7.3.
+
 ``maxRatioMessage``
 ~~~~~~~~~~~~~~~~~~~
 
@@ -477,6 +493,10 @@ Parameter             Description
 If set, the aspect ratio (``width / height``) of the image file must be greater
 than or equal to this value.
 
+.. versionadded:: 7.3
+
+    The ``minRatio`` option support for SVG files was introduced in Symfony 7.3.
+
 ``minRatioMessage``
 ~~~~~~~~~~~~~~~~~~~
 

From 3596f8c2b09f3380773a42a38b30f152fada315c Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Thu, 2 Jan 2025 12:59:47 +0100
Subject: [PATCH 450/747] Add ifFalse()

---
 components/config/definition.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/components/config/definition.rst b/components/config/definition.rst
index 0e626931568..24c142ec5a5 100644
--- a/components/config/definition.rst
+++ b/components/config/definition.rst
@@ -815,6 +815,7 @@ A validation rule always has an "if" part. You can specify this part in
 the following ways:
 
 - ``ifTrue()``
+- ``ifFalse()``
 - ``ifString()``
 - ``ifNull()``
 - ``ifEmpty()``
@@ -833,6 +834,10 @@ A validation rule also requires a "then" part:
 Usually, "then" is a closure. Its return value will be used as a new value
 for the node, instead of the node's original value.
 
+.. versionadded:: 7.3
+
+    The ``ifFalse()`` method was introduced in Symfony 7.3.
+
 Configuring the Node Path Separator
 -----------------------------------
 

From 0008e5b1a76566acbdb0e6e4fd5e752a31950eea Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Thu, 2 Jan 2025 13:34:31 +0100
Subject: [PATCH 451/747] Fix build

---
 security.rst | 1 -
 1 file changed, 1 deletion(-)

diff --git a/security.rst b/security.rst
index 79bad3f2254..d684ba09ba7 100644
--- a/security.rst
+++ b/security.rst
@@ -2966,4 +2966,3 @@ Authorization (Denying Access)
 .. _`Login CSRF attacks`: https://en.wikipedia.org/wiki/Cross-site_request_forgery#Forging_login_requests
 .. _`PHP date relative formats`: https://www.php.net/manual/en/datetime.formats.php#datetime.formats.relative
 .. _`Oauth2-client`: https://github.com/thephpleague/oauth2-client
-.. _`SensitiveParameter PHP attribute`: https://www.php.net/manual/en/class.sensitiveparameter.php

From e1c23c76557c1bad82005f61effb685fba775c6c Mon Sep 17 00:00:00 2001
From: Nate Wiebe <nate@symetricproductions.com>
Date: Thu, 2 Jan 2025 10:20:16 -0500
Subject: [PATCH 452/747] Add docs for is_granted_for_user() function

---
 reference/twig_reference.rst | 21 +++++++++++++++++++++
 security.rst                 | 11 +++++++++++
 2 files changed, 32 insertions(+)

diff --git a/reference/twig_reference.rst b/reference/twig_reference.rst
index d8b802dd73e..4485494bd9c 100644
--- a/reference/twig_reference.rst
+++ b/reference/twig_reference.rst
@@ -174,6 +174,27 @@ Returns ``true`` if the current user has the given role.
 Optionally, an object can be passed to be used by the voter. More information
 can be found in :ref:`security-template`.
 
+is_granted_for_user
+~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: twig
+
+    {{ is_granted_for_user(user, attribute, subject = null, field = null) }}
+
+``user``
+    **type**: ``object``
+``attribute``
+    **type**: ``string``
+``subject`` *(optional)*
+    **type**: ``object``
+``field`` *(optional)*
+    **type**: ``string``
+
+Returns ``true`` if the user is authorized for the specified attribute.
+
+Optionally, an object can be passed to be used by the voter. More information
+can be found in :ref:`security-template`.
+
 logout_path
 ~~~~~~~~~~~
 
diff --git a/security.rst b/security.rst
index 8026c63484b..7fe452e4fae 100644
--- a/security.rst
+++ b/security.rst
@@ -2549,6 +2549,17 @@ the built-in ``is_granted()`` helper function in any Twig template:
 
 .. _security-isgranted:
 
+Similarly, if you want to check if a specific user has a certain role, you can use
+the built-in ``is_granted_for_user()`` helper function:
+
+.. code-block:: html+twig
+
+    {% if is_granted_for_user(user, 'ROLE_ADMIN') %}
+        <a href="...">Delete</a>
+    {% endif %}
+
+.. _security-isgrantedforuser:
+
 Securing other Services
 .......................
 

From ddf1ad3975a30bd1b3fce6528c4795646674508e Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 3 Jan 2025 13:17:39 +0100
Subject: [PATCH 453/747] Add the missing versionadded directive

---
 reference/twig_reference.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/reference/twig_reference.rst b/reference/twig_reference.rst
index 4485494bd9c..e01fa3f80e3 100644
--- a/reference/twig_reference.rst
+++ b/reference/twig_reference.rst
@@ -177,6 +177,10 @@ can be found in :ref:`security-template`.
 is_granted_for_user
 ~~~~~~~~~~~~~~~~~~~
 
+.. versionadded:: 7.3
+
+    The ``is_granted_for_user()`` function was introduced in Symfony 7.3.
+
 .. code-block:: twig
 
     {{ is_granted_for_user(user, attribute, subject = null, field = null) }}

From effffa3bb0bcdbb7016d7bd415cd23c4f01fd948 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 3 Jan 2025 14:55:02 +0100
Subject: [PATCH 454/747] Minor tweak

---
 frontend/asset_mapper.rst | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index 81e91c1fc9d..d68c77c0105 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -747,11 +747,9 @@ and which file extensions should be compressed:
 Now, when running the ``asset-map:compile`` command, all matching files will be
 compressed in the configured format and at the highest compression level. The
 compressed files are created with the same name as the original but with the
-``.br``, ``.zst``, or ``.gz`` extension appended. Web servers that support asset
-precompression will use the compressed assets automatically, so there's nothing
-else to configure in your server.
+``.br``, ``.zst``, or ``.gz`` extension appended.
 
-Finally, you need to configure your web server to serve the precompressed assets
+Then, you need to configure your web server to serve the precompressed assets
 instead of the original ones:
 
 .. configuration-block::

From 9b65586c1ee8ec15873d290b6eaa01e8bd2dc062 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 3 Jan 2025 16:43:16 +0100
Subject: [PATCH 455/747] Fix build

---
 validation/custom_constraint.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/validation/custom_constraint.rst b/validation/custom_constraint.rst
index 990e1de9371..59da9e60568 100644
--- a/validation/custom_constraint.rst
+++ b/validation/custom_constraint.rst
@@ -66,7 +66,7 @@ Constraint with Private Properties
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Constraints are cached for performance reasons. To achieve this, the base
-``Constraint`` class uses PHP's :phpfunction:`get_object_vars()` function, which
+``Constraint`` class uses PHP's :phpfunction:`get_object_vars` function, which
 excludes private properties of child classes.
 
 If your constraint defines private properties, you must explicitly include them

From 1272701ec6e1d15e9bf21d6ab55445d6f68838ba Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 3 Jan 2025 16:19:25 +0100
Subject: [PATCH 456/747] [DependencyInjection] Make #[AsTaggedItem] repeatable

---
 service_container/tags.rst | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/service_container/tags.rst b/service_container/tags.rst
index 270d6702f5a..bf50a191ba3 100644
--- a/service_container/tags.rst
+++ b/service_container/tags.rst
@@ -1281,4 +1281,19 @@ be used directly on the class of the service you want to configure::
         // ...
     }
 
+You can apply the ``#[AsTaggedItem]`` attribute multiple times to register the
+same service under different indexes:
+
+    #[AsTaggedItem(index: 'handler_one', priority: 5)]
+    #[AsTaggedItem(index: 'handler_two', priority: 20)]
+    class SomeService
+    {
+        // ...
+    }
+
+.. versionadded:: 7.3
+
+    The feature to apply the ``#[AsTaggedItem]`` attribute multiple times was
+    introduced in Symfony 7.3.
+
 .. _`PHP constructor promotion`: https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion

From 9d4972de1863f3a028c6ce5d5e8d4ad2ac866201 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 3 Jan 2025 16:52:36 +0100
Subject: [PATCH 457/747] Minor reword

---
 security.rst | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/security.rst b/security.rst
index baa1a32a3a7..92367f29a88 100644
--- a/security.rst
+++ b/security.rst
@@ -2596,12 +2596,13 @@ want to include extra details only for users that have a ``ROLE_SALES_ADMIN`` ro
           // ...
       }
 
+
 .. tip::
 
-    Using ``isGranted()`` checks authorization against the currently logged in user. If you need to check
-    against a user that is not the one logged in or if checking authorization when the user session is not
-    available in a CLI context (example: message queue, cronjob) ``isGrantedForUser()`` can be used to set the
-    target user explicitly.
+    The ``isGranted()`` method checks authorization for the currently logged-in user.
+    If you need to check authorization for a different user or when the user session
+    is unavailable (e.g., in a CLI context such as a message queue or cron job), you
+    can use the ``isGrantedForUser()`` method to explicitly set the target user.
 
     .. versionadded:: 7.3
 

From 1afb8ebf3663a634108eac91b3d74ee20631d0af Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 3 Jan 2025 15:57:26 +0100
Subject: [PATCH 458/747] [HttpFoundation] Generate url-safe hashes for signed
 urls

---
 routing.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/routing.rst b/routing.rst
index ef3287dd1be..4ab0dce2a82 100644
--- a/routing.rst
+++ b/routing.rst
@@ -2802,6 +2802,11 @@ argument of :method:`Symfony\\Component\\HttpFoundation\\UriSigner::sign`::
 
     The feature to add an expiration date for a signed URI was introduced in Symfony 7.1.
 
+.. versionadded:: 7.3
+
+    Starting with Symfony 7.3, signed URI hashes no longer include the ``/`` or
+    ``+`` characters, as these may cause issues with certain clients.
+
 Troubleshooting
 ---------------
 

From ab691630aaeeabe52ae7717be558faa560968169 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Mon, 6 Jan 2025 09:11:25 +0100
Subject: [PATCH 459/747] [Yaml] Add support for dumping `null` as an empty
 value by using the `Yaml::DUMP_NULL_AS_EMPTY` flag

---
 components/yaml.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/components/yaml.rst b/components/yaml.rst
index 30f715a7a24..58436adffc2 100644
--- a/components/yaml.rst
+++ b/components/yaml.rst
@@ -428,6 +428,16 @@ you can dump them as ``~`` with the ``DUMP_NULL_AS_TILDE`` flag::
     $dumped = Yaml::dump(['foo' => null], 2, 4, Yaml::DUMP_NULL_AS_TILDE);
     // foo: ~
 
+Another valid representation of the ``null`` value is an empty string. You can
+use the ``DUMP_NULL_AS_EMPTY`` flag to dump null values as empty strings::
+
+    $dumped = Yaml::dump(['foo' => null], 2, 4, Yaml::DUMP_NULL_AS_EMPTY);
+    // foo:
+
+.. versionadded:: 7.3
+
+    The ``DUMP_NULL_AS_EMPTY`` flag was introduced in Symfony 7.3.
+
 Dumping Numeric Keys as Strings
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From 7d7e77cafbabba22b2443f4edc9fc13e3aba1bdf Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Mon, 6 Jan 2025 20:48:52 +0100
Subject: [PATCH 460/747] [PropertyInfo] Add
 PropertyDescriptionExtractorInterface to PhpStanExtractor

---
 components/property_info.rst | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/components/property_info.rst b/components/property_info.rst
index 2e1ee42dd3f..0ff1768441a 100644
--- a/components/property_info.rst
+++ b/components/property_info.rst
@@ -469,7 +469,18 @@ information from annotations of properties and methods, such as ``@var``,
     use App\Domain\Foo;
 
     $phpStanExtractor = new PhpStanExtractor();
+
+    // Type information.
     $phpStanExtractor->getTypesFromConstructor(Foo::class, 'bar');
+    // Description information.
+    $phpStanExtractor->getShortDescription($class, 'bar');
+    $phpStanExtractor->getLongDescription($class, 'bar');
+
+.. versionadded:: 7.3
+
+    The :method:`Symfony\\Component\\PropertyInfo\\Extractor\\PhpStanExtractor::getShortDescription`
+    and :method:`Symfony\\Component\\PropertyInfo\\Extractor\\PhpStanExtractor::getLongDescription`
+    methods were introduced in Symfony 7.3.
 
 SerializerExtractor
 ~~~~~~~~~~~~~~~~~~~

From 6d16cd8b4e41fa0b1686c44edb93b1f77023cd6f Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Mon, 6 Jan 2025 21:15:30 +0100
Subject: [PATCH 461/747] [Mailer] Add retry_period option for email transport

---
 mailer.rst | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/mailer.rst b/mailer.rst
index 4f0619147ad..8cc0d8641e3 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -331,6 +331,17 @@ The failover-transport starts using the first transport and if it fails, it
 will retry the same delivery with the next transports until one of them succeeds
 (or until all of them fail).
 
+By default, the delivery will be retried 60 seconds after previous sending failed.
+You can change the retry period by setting the ``retry_period`` option in the DSN:
+
+.. code-block:: env
+
+    MAILER_DSN="failover(postmark+api://ID@default sendgrid+smtp://KEY@default)?retry_period=15"
+
+.. versionadded:: 7.3
+
+    The ``retry_period`` option was introduced in Symfony 7.3.
+
 Load Balancing
 ~~~~~~~~~~~~~~
 
@@ -351,6 +362,17 @@ As with the failover transport, round-robin retries deliveries until
 a transport succeeds (or all fail). In contrast to the failover transport,
 it *spreads* the load across all its transports.
 
+By default, the delivery will be retried 60 seconds after previous sending failed.
+You can change the retry period by setting the ``retry_period`` option in the DSN:
+
+.. code-block:: env
+
+    MAILER_DSN="roundrobin(postmark+api://ID@default sendgrid+smtp://KEY@default)?retry_period=15"
+
+.. versionadded:: 7.3
+
+    The ``retry_period`` option was introduced in Symfony 7.3.
+
 TLS Peer Verification
 ~~~~~~~~~~~~~~~~~~~~~
 

From 7d94c8e8fc64032721af5415d8a3c0fe018ecf71 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 7 Jan 2025 08:42:04 +0100
Subject: [PATCH 462/747] Minor reword

---
 mailer.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index 8cc0d8641e3..4fd02eb84d7 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -331,8 +331,8 @@ The failover-transport starts using the first transport and if it fails, it
 will retry the same delivery with the next transports until one of them succeeds
 (or until all of them fail).
 
-By default, the delivery will be retried 60 seconds after previous sending failed.
-You can change the retry period by setting the ``retry_period`` option in the DSN:
+By default, delivery is retried 60 seconds after a failed attempt. You can adjust
+the retry period by setting the ``retry_period`` option in the DSN:
 
 .. code-block:: env
 
@@ -362,8 +362,8 @@ As with the failover transport, round-robin retries deliveries until
 a transport succeeds (or all fail). In contrast to the failover transport,
 it *spreads* the load across all its transports.
 
-By default, the delivery will be retried 60 seconds after previous sending failed.
-You can change the retry period by setting the ``retry_period`` option in the DSN:
+By default, delivery is retried 60 seconds after a failed attempt. You can adjust
+the retry period by setting the ``retry_period`` option in the DSN:
 
 .. code-block:: env
 

From d1400d406951f664bd159e38eab33c5a93cb73e9 Mon Sep 17 00:00:00 2001
From: Iker Ibarguren <ikerib@users.noreply.github.com>
Date: Tue, 7 Jan 2025 09:51:40 +0100
Subject: [PATCH 463/747] Update notifier.rst

Brevo third-party service now supports webhooks.
---
 notifier.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/notifier.rst b/notifier.rst
index 36fbd5ada89..5b3f12a67fa 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -76,7 +76,7 @@ Service
                     **Webhook support**: No
 `Brevo`_            **Install**: ``composer require symfony/brevo-notifier`` \
                     **DSN**: ``brevo://API_KEY@default?sender=SENDER`` \
-                    **Webhook support**: No
+                    **Webhook support**: Yes
 `Clickatell`_       **Install**: ``composer require symfony/clickatell-notifier`` \
                     **DSN**: ``clickatell://ACCESS_TOKEN@default?from=FROM`` \
                     **Webhook support**: No

From e4f8ff86daa93eab17172a0fd001caccd5c93e55 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 7 Jan 2025 12:04:07 +0100
Subject: [PATCH 464/747] Add a versionadded directive

---
 notifier.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/notifier.rst b/notifier.rst
index 5b3f12a67fa..090f4db2007 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -236,6 +236,10 @@ Service
 
     The ``Primotexto``, ``Sipgate`` and ``Sweego`` integrations were introduced in Symfony 7.2.
 
+.. versionadded:: 7.3
+
+    Webhook support for the ``Brevo`` integration was introduced in Symfony 7.3.
+
 .. deprecated:: 7.1
 
     The `Sms77`_ integration is deprecated since

From 17a46adc143905ee469e48118039c7e8f66760b5 Mon Sep 17 00:00:00 2001
From: Maxime Doutreluingne <maxime.doutreluingne@gmail.com>
Date: Sun, 5 Jan 2025 17:34:40 +0100
Subject: [PATCH 465/747] [Validator] [DateTime] Add ``format`` to error
 messages

---
 reference/constraints/DateTime.rst | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/reference/constraints/DateTime.rst b/reference/constraints/DateTime.rst
index f6bcce7e5f5..ffcfbf55dda 100644
--- a/reference/constraints/DateTime.rst
+++ b/reference/constraints/DateTime.rst
@@ -99,11 +99,16 @@ This message is shown if the underlying data is not a valid datetime.
 
 You can use the following parameters in this message:
 
-===============  ==============================================================
-Parameter        Description
-===============  ==============================================================
-``{{ value }}``  The current (invalid) value
-``{{ label }}``  Corresponding form field label
-===============  ==============================================================
+================  ==============================================================
+Parameter         Description
+================  ==============================================================
+``{{ value }}``   The current (invalid) value
+``{{ label }}``   Corresponding form field label
+``{{ format }}``  The date format defined in ``format``
+================  ==============================================================
+
+.. versionadded:: 7.3
+
+    The ``{{ format }}`` parameter was introduced in Symfony 7.3.
 
 .. include:: /reference/constraints/_payload-option.rst.inc

From 45113124f7b2affdcceae4460f218b4efc740839 Mon Sep 17 00:00:00 2001
From: tcoch <tcochard@outlook.com>
Date: Mon, 6 Jan 2025 09:22:34 +0100
Subject: [PATCH 466/747] [String] Add `AbstractString::pascal()` method

---
 string.rst | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/string.rst b/string.rst
index 43d3a236ab6..e51e7d1b502 100644
--- a/string.rst
+++ b/string.rst
@@ -234,8 +234,10 @@ Methods to Change Case
     u('Foo: Bar-baz.')->snake(); // 'foo_bar_baz'
     // changes all graphemes/code points to kebab-case
     u('Foo: Bar-baz.')->kebab(); // 'foo-bar-baz'
-    // other cases can be achieved by chaining methods. E.g. PascalCase:
-    u('Foo: Bar-baz.')->camel()->title(); // 'FooBarBaz'
+    // changes all graphemes/code points to PascalCase
+    u('Foo: Bar-baz.')->pascal(); // 'FooBarBaz'
+    // other cases can be achieved by chaining methods, e.g. :
+    u('Foo: Bar-baz.')->camel()->upper(); // 'FOOBARBAZ'
 
 .. versionadded:: 7.1
 
@@ -246,6 +248,10 @@ Methods to Change Case
 
     The ``kebab()`` method was introduced in Symfony 7.2.
 
+.. versionadded:: 7.3
+
+    The ``pascal()`` method was introduced in Symfony 7.3.
+
 The methods of all string classes are case-sensitive by default. You can perform
 case-insensitive operations with the ``ignoreCase()`` method::
 

From 951f461e329cb0c8f275ca9100b2a5789844afec Mon Sep 17 00:00:00 2001
From: Mathias Arlaud <mathias.arlaud@gmail.com>
Date: Tue, 7 Jan 2025 16:08:07 +0100
Subject: [PATCH 467/747] [TypeInfo] Add `accepts` method

---
 components/type_info.rst | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index e7062c5f249..70280d9a348 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -114,7 +114,7 @@ Advanced Usages
 The TypeInfo component provides various methods to manipulate and check types,
 depending on your needs.
 
-Checking a **simple type**::
+**Identify** a type::
 
     // define a simple integer type
     $type = Type::int();
@@ -141,6 +141,23 @@ Checking a **simple type**::
     $type->isIdentifiedBy(DummyParent::class);     // true
     $type->isIdentifiedBy(DummyInterface::class);  // true
 
+Checking if a type **accepts a value**::
+
+    $type = Type::int();
+    // check if the type accepts a given value
+    $type->accepts(123); // true
+    $type->accepts('z'); // false
+
+    $type = Type::union(Type::string(), Type::int());
+    // now the second check is true because the union type accepts either a int and a string value
+    $type->accepts(123); // true
+    $type->accepts('z'); // true
+
+.. versionadded:: 7.3
+
+    The :method:`Symfony\\Component\\TypeInfo\\Type::accepts`
+    method was introduced in Symfony 7.3.
+
 Using callables for **complex checks**::
 
     class Foo

From b4f8f6bf5f596664eb36c6311107b0b0056fd166 Mon Sep 17 00:00:00 2001
From: tcoch <tcochard@outlook.com>
Date: Mon, 6 Jan 2025 17:22:10 +0100
Subject: [PATCH 468/747] [Validator] Add Slug constraint

---
 reference/constraints/Slug.rst    | 119 ++++++++++++++++++++++++++++++
 reference/constraints/map.rst.inc |   1 +
 2 files changed, 120 insertions(+)
 create mode 100644 reference/constraints/Slug.rst

diff --git a/reference/constraints/Slug.rst b/reference/constraints/Slug.rst
new file mode 100644
index 00000000000..5b7661b4aba
--- /dev/null
+++ b/reference/constraints/Slug.rst
@@ -0,0 +1,119 @@
+Slug
+====
+
+.. versionadded:: 7.3
+
+    The ``Slug`` constraint was introduced in Symfony 7.3.
+
+Validates that a value is a slug.
+A slug is a string that, by default, matches the regex ``/^[a-z0-9]+(?:-[a-z0-9]+)*$/``.
+
+.. include:: /reference/constraints/_empty-values-are-valid.rst.inc
+
+==========  ===================================================================
+Applies to  :ref:`property or method <validation-property-target>`
+Class       :class:`Symfony\\Component\\Validator\\Constraints\\Slug`
+Validator   :class:`Symfony\\Component\\Validator\\Constraints\\SlugValidator`
+==========  ===================================================================
+
+Basic Usage
+-----------
+
+The ``Slug`` constraint can be applied to a property or a "getter" method:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Entity/Author.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+
+        class Author
+        {
+            #[Assert\Slug]
+            protected string $slug;
+        }
+
+    .. code-block:: yaml
+
+        # config/validator/validation.yaml
+        App\Entity\Author:
+            properties:
+                slug:
+                    - Slug: ~
+
+    .. code-block:: xml
+
+        <!-- config/validator/validation.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
+
+            <class name="App\Entity\Author">
+                <property name="slug">
+                    <constraint name="Slug"/>
+                </property>
+            </class>
+        </constraint-mapping>
+
+    .. code-block:: php
+
+        // src/Entity/Author.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+        use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+        class Author
+        {
+            // ...
+
+            public static function loadValidatorMetadata(ClassMetadata $metadata): void
+            {
+                $metadata->addPropertyConstraint('slug', new Assert\Slug());
+            }
+        }
+
+Examples of valid values :
+
+* foobar
+* foo-bar
+* foo123
+* foo-123bar
+
+Upper case characters would result in an violation of this constraint.
+
+Options
+-------
+
+``regex``
+~~~~~~~~~
+
+**type**: ``string`` default: ``/^[a-z0-9]+(?:-[a-z0-9]+)*$/``
+
+This option allows you to modify the regular expression pattern that the input will be matched against
+via the :phpfunction:`preg_match` PHP function.
+
+If you need to use it, you might also want to take a look at the :doc:`Regex constraint <Regex>`.
+
+``message``
+~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``This value is not a valid slug``
+
+This is the message that will be shown if this validator fails.
+
+You can use the following parameters in this message:
+
+=================  ==============================================================
+Parameter          Description
+=================  ==============================================================
+``{{ value }}``    The current (invalid) value
+=================  ==============================================================
+
+.. include:: /reference/constraints/_groups-option.rst.inc
+
+.. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/map.rst.inc b/reference/constraints/map.rst.inc
index f23f5b71aa3..58801a8c653 100644
--- a/reference/constraints/map.rst.inc
+++ b/reference/constraints/map.rst.inc
@@ -33,6 +33,7 @@ String Constraints
 * :doc:`NotCompromisedPassword </reference/constraints/NotCompromisedPassword>`
 * :doc:`PasswordStrength </reference/constraints/PasswordStrength>`
 * :doc:`Regex </reference/constraints/Regex>`
+* :doc:`Slug </reference/constraints/Slug>`
 * :doc:`Ulid </reference/constraints/Ulid>`
 * :doc:`Url </reference/constraints/Url>`
 * :doc:`UserPassword </reference/constraints/UserPassword>`

From d688f6312c64050123f0c27b0871f80ab63b677c Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 7 Jan 2025 17:56:09 +0100
Subject: [PATCH 469/747] Minor tweaks

---
 reference/constraints/Slug.rst | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/reference/constraints/Slug.rst b/reference/constraints/Slug.rst
index 5b7661b4aba..2eb82cd9c10 100644
--- a/reference/constraints/Slug.rst
+++ b/reference/constraints/Slug.rst
@@ -5,8 +5,8 @@ Slug
 
     The ``Slug`` constraint was introduced in Symfony 7.3.
 
-Validates that a value is a slug.
-A slug is a string that, by default, matches the regex ``/^[a-z0-9]+(?:-[a-z0-9]+)*$/``.
+Validates that a value is a slug. By default, a slug is a string that matches
+the following regular expression: ``/^[a-z0-9]+(?:-[a-z0-9]+)*$/``.
 
 .. include:: /reference/constraints/_empty-values-are-valid.rst.inc
 
@@ -19,7 +19,7 @@ Validator   :class:`Symfony\\Component\\Validator\\Constraints\\SlugValidator`
 Basic Usage
 -----------
 
-The ``Slug`` constraint can be applied to a property or a "getter" method:
+The ``Slug`` constraint can be applied to a property or a getter method:
 
 .. configuration-block::
 
@@ -77,14 +77,14 @@ The ``Slug`` constraint can be applied to a property or a "getter" method:
             }
         }
 
-Examples of valid values :
+Examples of valid values:
 
 * foobar
 * foo-bar
 * foo123
 * foo-123bar
 
-Upper case characters would result in an violation of this constraint.
+Uppercase characters would result in an violation of this constraint.
 
 Options
 -------
@@ -94,8 +94,8 @@ Options
 
 **type**: ``string`` default: ``/^[a-z0-9]+(?:-[a-z0-9]+)*$/``
 
-This option allows you to modify the regular expression pattern that the input will be matched against
-via the :phpfunction:`preg_match` PHP function.
+This option allows you to modify the regular expression pattern that the input
+will be matched against via the :phpfunction:`preg_match` PHP function.
 
 If you need to use it, you might also want to take a look at the :doc:`Regex constraint <Regex>`.
 

From 693b758160d580d9e5bbdb6e0e8b4310baf2d5f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20Andr=C3=A9?= <smn.andre@gmail.com>
Date: Wed, 8 Jan 2025 06:29:55 +0100
Subject: [PATCH 470/747] [Security] Remove mention of is_granted_ `$field`
 argument

The third argument of is_granted / is_granted_for_user is undocumented (except on this page) (neither on Symfony docs, code, nor on... Symfony ACL Bundle docs).

It must be kept and maintained for BC reasons. But it can be missleading/frustrating to show this argument to users, when they cannot use it with a standard/recommended Symfony installation.

And if they just test it, the error could lead them to believe the AclBundle needs to be installed to use the `is_granted` function(s).

As suggested in https://github.com/symfony/symfony/pull/59282#issuecomment-2569716817 I believe "not showing it" is the "best" solution here.
---
 reference/twig_reference.rst | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/reference/twig_reference.rst b/reference/twig_reference.rst
index e01fa3f80e3..acbab2f3817 100644
--- a/reference/twig_reference.rst
+++ b/reference/twig_reference.rst
@@ -160,14 +160,12 @@ is_granted
 
 .. code-block:: twig
 
-    {{ is_granted(role, object = null, field = null) }}
+    {{ is_granted(role, object = null) }}
 
 ``role``
     **type**: ``string``
 ``object`` *(optional)*
     **type**: ``object``
-``field`` *(optional)*
-    **type**: ``string``
 
 Returns ``true`` if the current user has the given role.
 
@@ -183,7 +181,7 @@ is_granted_for_user
 
 .. code-block:: twig
 
-    {{ is_granted_for_user(user, attribute, subject = null, field = null) }}
+    {{ is_granted_for_user(user, attribute, subject = null) }}
 
 ``user``
     **type**: ``object``
@@ -191,8 +189,6 @@ is_granted_for_user
     **type**: ``string``
 ``subject`` *(optional)*
     **type**: ``object``
-``field`` *(optional)*
-    **type**: ``string``
 
 Returns ``true`` if the user is authorized for the specified attribute.
 

From 23800a97fa5114849320dac166b80ff97b3d2d46 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 8 Jan 2025 10:18:55 +0100
Subject: [PATCH 471/747] Minor tweak

---
 components/type_info.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index 70280d9a348..47fe9dfd9ba 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -149,7 +149,7 @@ Checking if a type **accepts a value**::
     $type->accepts('z'); // false
 
     $type = Type::union(Type::string(), Type::int());
-    // now the second check is true because the union type accepts either a int and a string value
+    // now the second check is true because the union type accepts either an int or a string value
     $type->accepts(123); // true
     $type->accepts('z'); // true
 

From cf53d1914e874def9e39324e6c5ad32e0b441f23 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joachim=20L=C3=B8vgaard?= <joachim@loevgaard.dk>
Date: Wed, 8 Jan 2025 12:06:09 +0100
Subject: [PATCH 472/747] Fix typo

---
 components/type_info.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index e7062c5f249..2a92a3db63e 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -106,7 +106,7 @@ PHP package required for string resolving. Then, follow these steps::
 
     $typeResolver = TypeResolver::create();
     $typeResolver->resolve(new \ReflectionProperty(Dummy::class, 'id')); // returns an "int" Type
-    $typeResolver->resolve(new \ReflectionProperty(Dummy::class, 'id')); // returns a collection with "int" as key and "string" as values Type
+    $typeResolver->resolve(new \ReflectionProperty(Dummy::class, 'tags')); // returns a collection with "int" as key and "string" as values Type
 
 Advanced Usages
 ~~~~~~~~~~~~~~~

From ed80f8b78a6714ed0c092e7cf90eb98afecf75be Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Wed, 8 Jan 2025 22:05:23 +0100
Subject: [PATCH 473/747] revert webhook support for the Brevo Notifier bridge

---
 notifier.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/notifier.rst b/notifier.rst
index 090f4db2007..f74ff92009e 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -76,7 +76,7 @@ Service
                     **Webhook support**: No
 `Brevo`_            **Install**: ``composer require symfony/brevo-notifier`` \
                     **DSN**: ``brevo://API_KEY@default?sender=SENDER`` \
-                    **Webhook support**: Yes
+                    **Webhook support**: No
 `Clickatell`_       **Install**: ``composer require symfony/clickatell-notifier`` \
                     **DSN**: ``clickatell://ACCESS_TOKEN@default?from=FROM`` \
                     **Webhook support**: No

From fb028aa7e77e8a2324b3b65e4e9823045d26ef73 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 9 Jan 2025 12:24:39 +0100
Subject: [PATCH 474/747] Remove an uneeded versionadded directive

---
 notifier.rst | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/notifier.rst b/notifier.rst
index f74ff92009e..36fbd5ada89 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -236,10 +236,6 @@ Service
 
     The ``Primotexto``, ``Sipgate`` and ``Sweego`` integrations were introduced in Symfony 7.2.
 
-.. versionadded:: 7.3
-
-    Webhook support for the ``Brevo`` integration was introduced in Symfony 7.3.
-
 .. deprecated:: 7.1
 
     The `Sms77`_ integration is deprecated since

From bb76fd9fee26080dfa8795528f472aed5d8fcf64 Mon Sep 17 00:00:00 2001
From: Ninos Ego <me@ninosego.de>
Date: Wed, 8 Jan 2025 23:52:31 +0100
Subject: [PATCH 475/747] [Validator] Add note to `version` option in `Cidr`
 constraint

---
 reference/constraints/Cidr.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/reference/constraints/Cidr.rst b/reference/constraints/Cidr.rst
index 24abeb57338..00125c72b39 100644
--- a/reference/constraints/Cidr.rst
+++ b/reference/constraints/Cidr.rst
@@ -126,6 +126,12 @@ Parameter        Description
 This determines exactly *how* the CIDR notation is validated and can take one
 of :ref:`IP version ranges <reference-constraint-ip-version>`.
 
+.. note::
+
+    IP range (``*_private``, ``*_reserved``) is only validating against IP, but not the whole
+    netmask. You need to set the ``{{ min }}`` value for the netmask to harden the validation a bit.
+    For example, ``9.0.0.0/6`` results to be ``*_public``, but also uses ``10.0.0.0/8`` range (``*_private``).
+
 .. versionadded:: 7.1
 
     The support of all IP version ranges was introduced in Symfony 7.1.

From 57739755111fed2beca51857df73a7f59459fb81 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 9 Jan 2025 13:02:08 +0100
Subject: [PATCH 476/747] Minor reword

---
 reference/constraints/Cidr.rst | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/reference/constraints/Cidr.rst b/reference/constraints/Cidr.rst
index 61233d875ce..78a5b6c7167 100644
--- a/reference/constraints/Cidr.rst
+++ b/reference/constraints/Cidr.rst
@@ -128,9 +128,11 @@ of :ref:`IP version ranges <reference-constraint-ip-version>`.
 
 .. note::
 
-    IP range (``*_private``, ``*_reserved``) is only validating against IP, but not the whole
-    netmask. You need to set the ``{{ min }}`` value for the netmask to harden the validation a bit.
-    For example, ``9.0.0.0/6`` results to be ``*_public``, but also uses ``10.0.0.0/8`` range (``*_private``).
+    The IP range checks (e.g., ``*_private``, ``*_reserved``) validate only the
+    IP address, not the entire netmask. To improve validation, you can set the
+    ``{{ min }}`` value for the netmask. For example, the range ``9.0.0.0/6`` is
+    considered ``*_public``, but it also includes the ``10.0.0.0/8`` range, which
+    is categorized as ``*_private``.
 
 .. versionadded:: 7.1
 

From f8667f57029ad20b615c6c7f42d13bc02df86fa5 Mon Sep 17 00:00:00 2001
From: Vincent Langlet <vincentlanglet@hotmail.fr>
Date: Mon, 6 Jan 2025 21:16:06 +0100
Subject: [PATCH 477/747] [OptionsResolver] Support union of types

---
 components/options_resolver.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/components/options_resolver.rst b/components/options_resolver.rst
index ff25f9e0fc4..266911bf13d 100644
--- a/components/options_resolver.rst
+++ b/components/options_resolver.rst
@@ -305,13 +305,20 @@ correctly. To validate the types of the options, call
 
             // specify multiple allowed types
             $resolver->setAllowedTypes('port', ['null', 'int']);
+            // which is similar to
+            $resolver->setAllowedTypes('port', 'int|null');
 
             // check all items in an array recursively for a type
             $resolver->setAllowedTypes('dates', 'DateTime[]');
             $resolver->setAllowedTypes('ports', 'int[]');
+            $resolver->setAllowedTypes('endpoints', '(int|string)[]');
         }
     }
 
+.. versionadded:: 7.3
+
+    Union of type, using the ``|`` syntax, was introduced in Symfony 7.3.
+
 You can pass any type for which an ``is_<type>()`` function is defined in PHP.
 You may also pass fully qualified class or interface names (which is checked
 using ``instanceof``). Additionally, you can validate all items in an array

From ca50eeb570eb13b2c35b7fa02f199bfc509755d8 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 9 Jan 2025 15:29:40 +0100
Subject: [PATCH 478/747] Minor tweaks

---
 components/options_resolver.rst | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/components/options_resolver.rst b/components/options_resolver.rst
index 266911bf13d..95741a7e372 100644
--- a/components/options_resolver.rst
+++ b/components/options_resolver.rst
@@ -305,19 +305,20 @@ correctly. To validate the types of the options, call
 
             // specify multiple allowed types
             $resolver->setAllowedTypes('port', ['null', 'int']);
-            // which is similar to
+            // if you prefer, you can also use the following equivalent syntax
             $resolver->setAllowedTypes('port', 'int|null');
 
             // check all items in an array recursively for a type
             $resolver->setAllowedTypes('dates', 'DateTime[]');
             $resolver->setAllowedTypes('ports', 'int[]');
+            // the following syntax means "an array of integers or an array of strings"
             $resolver->setAllowedTypes('endpoints', '(int|string)[]');
         }
     }
 
 .. versionadded:: 7.3
 
-    Union of type, using the ``|`` syntax, was introduced in Symfony 7.3.
+    Defining type unions with the ``|`` syntax was introduced in Symfony 7.3.
 
 You can pass any type for which an ``is_<type>()`` function is defined in PHP.
 You may also pass fully qualified class or interface names (which is checked

From c532aed720a486a85ba26209cf7ad4185db5c0ec Mon Sep 17 00:00:00 2001
From: chx <chx1975@gmail.com>
Date: Mon, 6 Jan 2025 14:36:23 +0100
Subject: [PATCH 479/747] [DependencyInjection] Documented the new @> shorthand

---
 service_container/service_closures.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/service_container/service_closures.rst b/service_container/service_closures.rst
index cedbaaa2bf9..73dc17961fd 100644
--- a/service_container/service_closures.rst
+++ b/service_container/service_closures.rst
@@ -52,6 +52,14 @@ argument of type ``service_closure``:
                 # In case the dependency is optional
                 # arguments: [!service_closure '@?mailer']
 
+.. versionadded:: 7.3
+
+                # A shorthand is available
+                # arguments: ['@>mailer']
+
+                # It also works when the dependency is optional
+                # arguments: ['@>?mailer']
+
     .. code-block:: xml
 
         <!-- config/services.xml -->

From 250c35b812814ed105d1790213b9938a2e244666 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 10 Jan 2025 16:08:17 +0100
Subject: [PATCH 480/747] Reword

---
 service_container/service_closures.rst | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/service_container/service_closures.rst b/service_container/service_closures.rst
index 73dc17961fd..88b0ab64002 100644
--- a/service_container/service_closures.rst
+++ b/service_container/service_closures.rst
@@ -52,12 +52,11 @@ argument of type ``service_closure``:
                 # In case the dependency is optional
                 # arguments: [!service_closure '@?mailer']
 
-.. versionadded:: 7.3
-
-                # A shorthand is available
-                # arguments: ['@>mailer']
+            # you can also use the special '@>' syntax as a shortcut of '!service_closure'
+            App\Service\AnotherService:
+                arguments: ['@>mailer']
 
-                # It also works when the dependency is optional
+                # the shortcut also works for optional dependencies
                 # arguments: ['@>?mailer']
 
     .. code-block:: xml
@@ -98,6 +97,10 @@ argument of type ``service_closure``:
             //     ->args([service_closure('mailer')->ignoreOnInvalid()]);
         };
 
+.. versionadded:: 7.3
+
+    The ``@>`` shortcut syntax for YAML was introduced in Symfony 7.3.
+
 .. seealso::
 
     Service closures can be injected :ref:`by using autowiring <autowiring_closures>`

From 1960c77521d526199cc28a07d189d8e4ac2353a0 Mon Sep 17 00:00:00 2001
From: Javier Spagnoletti <phansys@gmail.com>
Date: Sat, 11 Jan 2025 03:10:57 -0300
Subject: [PATCH 481/747] [Doctrine] Use PDO constants in YAML configuration
 example

---
 reference/configuration/doctrine.rst | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/reference/configuration/doctrine.rst b/reference/configuration/doctrine.rst
index cd1852710e7..272ad6b6804 100644
--- a/reference/configuration/doctrine.rst
+++ b/reference/configuration/doctrine.rst
@@ -483,12 +483,12 @@ set up the connection using environment variables for the certificate paths:
                 server_version: '8.0.31'
                 driver: 'pdo_mysql'
                 options:
-                    # SSL private key (PDO::MYSQL_ATTR_SSL_KEY)
-                    1007: '%env(MYSQL_SSL_KEY)%'
-                    # SSL certificate (PDO::MYSQL_ATTR_SSL_CERT)
-                    1008: '%env(MYSQL_SSL_CERT)%'
-                    # SSL CA authority (PDO::MYSQL_ATTR_SSL_CA)
-                    1009: '%env(MYSQL_SSL_CA)%'
+                    # SSL private key
+                    !php/const 'PDO::MYSQL_ATTR_SSL_KEY': '%env(MYSQL_SSL_KEY)%'
+                    # SSL certificate
+                    !php/const 'PDO::MYSQL_ATTR_SSL_CERT': '%env(MYSQL_SSL_CERT)%'
+                    # SSL CA authority
+                    !php/const 'PDO::MYSQL_ATTR_SSL_CA': '%env(MYSQL_SSL_CA)%'
 
     .. code-block:: xml
 

From c880a8818fa495a6b34188bddd76b946e54e6d3a Mon Sep 17 00:00:00 2001
From: Javier Spagnoletti <phansys@gmail.com>
Date: Sat, 11 Jan 2025 03:14:50 -0300
Subject: [PATCH 482/747] [Doctrine] Use PDO constants in XML configuration
 example

---
 reference/configuration/doctrine.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/reference/configuration/doctrine.rst b/reference/configuration/doctrine.rst
index cd1852710e7..25621f60493 100644
--- a/reference/configuration/doctrine.rst
+++ b/reference/configuration/doctrine.rst
@@ -507,9 +507,9 @@ set up the connection using environment variables for the certificate paths:
                     server-version="8.0.31"
                     driver="pdo_mysql">
 
-                    <doctrine:option key="1007">%env(MYSQL_SSL_KEY)%</doctrine:option>
-                    <doctrine:option key="1008">%env(MYSQL_SSL_CERT)%</doctrine:option>
-                    <doctrine:option key="1009">%env(MYSQL_SSL_CA)%</doctrine:option>
+                    <doctrine:option key-type="constant" key="PDO::MYSQL_ATTR_SSL_KEY">%env(MYSQL_SSL_KEY)%</doctrine:option>
+                    <doctrine:option key-type="constant" key="PDO::MYSQL_ATTR_SSL_CERT">%env(MYSQL_SSL_CERT)%</doctrine:option>
+                    <doctrine:option key-type="constant" key="PDO::MYSQL_ATTR_SSL_CA">%env(MYSQL_SSL_CA)%</doctrine:option>
                 </doctrine:dbal>
             </doctrine:config>
         </container>

From 207933321946e82e537eece0022f2045e22c0ff8 Mon Sep 17 00:00:00 2001
From: Maxime Doutreluingne <maxime.doutreluingne@gmail.com>
Date: Sun, 12 Jan 2025 11:09:02 +0100
Subject: [PATCH 483/747] [FrameworkBundle] Remove ``--show-arguments`` option
 for ``debug:container``

---
 controller/value_resolver.rst | 2 +-
 service_container/debug.rst   | 3 ---
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/controller/value_resolver.rst b/controller/value_resolver.rst
index dbbea7bcc87..1844ff0c9be 100644
--- a/controller/value_resolver.rst
+++ b/controller/value_resolver.rst
@@ -396,7 +396,7 @@ command to see which argument resolvers are present and in which order they run:
 
 .. code-block:: terminal
 
-    $ php bin/console debug:container debug.argument_resolver.inner --show-arguments
+    $ php bin/console debug:container debug.argument_resolver.inner
 
 You can also configure the name passed to the ``ValueResolver`` attribute to target
 your resolver. Otherwise it will default to the service's id.
diff --git a/service_container/debug.rst b/service_container/debug.rst
index c09413e7213..0a7898108fb 100644
--- a/service_container/debug.rst
+++ b/service_container/debug.rst
@@ -51,6 +51,3 @@ its id:
 .. code-block:: terminal
 
     $ php bin/console debug:container App\Service\Mailer
-
-    # to show the service arguments:
-    $ php bin/console debug:container App\Service\Mailer --show-arguments

From e12afdd378e43587f1d9cfb06e8f5708146b2e76 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 13 Jan 2025 09:34:01 +0100
Subject: [PATCH 484/747] Add a versionadded directive

---
 service_container/debug.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/service_container/debug.rst b/service_container/debug.rst
index 0a7898108fb..aab6fa9529f 100644
--- a/service_container/debug.rst
+++ b/service_container/debug.rst
@@ -51,3 +51,9 @@ its id:
 .. code-block:: terminal
 
     $ php bin/console debug:container App\Service\Mailer
+
+.. versionadded:: 7.3
+
+    Starting in Symfony 7.3, this command displays the service arguments by default.
+    In earlier Symfony versions, you needed to use the ``--show-arguments`` option,
+    which is now deprecated.

From bcbf6f62d5bcc1119d89f5caccf75c73f5b68cf7 Mon Sep 17 00:00:00 2001
From: Wouter de Jong <wouter@wouterj.nl>
Date: Mon, 13 Jan 2025 16:25:18 +0100
Subject: [PATCH 485/747] [#20566] Add UX team description

---
 contributing/code/core_team.rst | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/contributing/code/core_team.rst b/contributing/code/core_team.rst
index 242f471947a..41e9a6cc3e3 100644
--- a/contributing/code/core_team.rst
+++ b/contributing/code/core_team.rst
@@ -34,7 +34,9 @@ The Symfony Core groups, in descending order of priority, are as follows:
 In addition, there are other groups created to manage specific topics:
 
 * **Security Team**: manages the whole security process (triaging reported vulnerabilities,
-  fixing the reported issues, coordinating the release of security fixes, etc.)
+  fixing the reported issues, coordinating the release of security fixes, etc.);
+
+* **Symfony UX Team**: manages the `UX repositories`_;
 
 * **Documentation Team**: manages the whole `symfony-docs repository`_.
 
@@ -71,7 +73,7 @@ Active Core Members
   * **Fabien Potencier** (`fabpot`_);
   * **Jérémy Derussé** (`jderusse`_).
 
-* **Symfony UX** (``@symfony/ux`` on GitHub):
+* **Symfony UX Team** (``@symfony/ux`` on GitHub):
 
   * **Ryan Weaver** (`weaverryan`_);
   * **Kevin Bond** (`kbond`_);
@@ -188,6 +190,7 @@ discretion of the **Project Leader**.
     violations, and minor CSS, JavaScript and HTML modifications.
 
 .. _`symfony-docs repository`: https://github.com/symfony/symfony-docs
+.. _`UX repositories`: https://github.com/symfony/ux
 .. _`fabpot`: https://github.com/fabpot/
 .. _`webmozart`: https://github.com/webmozart/
 .. _`Tobion`: https://github.com/Tobion/

From d46522ad4ae49ae8317ad5c762daac0227ed143a Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 14 Jan 2025 09:53:02 +0100
Subject: [PATCH 486/747] Add more details about the context variable

---
 reference/constraints/When.rst | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/reference/constraints/When.rst b/reference/constraints/When.rst
index 12b43fc7d63..2a05e58ee9c 100644
--- a/reference/constraints/When.rst
+++ b/reference/constraints/When.rst
@@ -163,7 +163,7 @@ validation of constraints won't be triggered.
 To learn more about the expression language syntax, see
 :doc:`/reference/formats/expression_language`.
 
-Depending on how you use the constraint, you have access to 1 or 3 variables
+Depending on how you use the constraint, you have access to different variables
 in your expression:
 
 ``this``
@@ -172,7 +172,13 @@ in your expression:
     The value of the property being validated (only available when
     the constraint is applied to a property).
 ``context``
-    This is the context that is used in validation
+    The :class:`Symfony\\Component\\Validator\\Context\\ExecutionContextInterface`
+    object that provides information such as the currently validated class, the
+    name of the currently validated property, the list of violations, etc.
+
+.. versionadded:: 7.2
+
+    The ``context`` variable in expressions was introduced in Symfony 7.2.
 
 The ``value`` variable can be used when you want to execute more complex
 validation based on its value:

From 1c51901e95a0d05284e311df419bc9828dc983c7 Mon Sep 17 00:00:00 2001
From: Farhad Hedayatifard <hf.farhad@gmail.com>
Date: Tue, 29 Oct 2024 21:10:14 +0330
Subject: [PATCH 487/747] [Mailer] feat(mailer): Add AhaSend Mailer doc

---
 .doctor-rst.yaml                              |    4 +-
 .github/workflows/ci.yaml                     |    2 +-
 _build/redirection_map                        |    5 +-
 .../serializer/serializer_workflow.svg        |    0
 .../serializer/serializer_workflow.dia        |  Bin
 bundles.rst                                   |    6 +-
 bundles/best_practices.rst                    |    2 +-
 bundles/extension.rst                         |    2 +-
 bundles/override.rst                          |    2 +-
 cache.rst                                     |    2 +-
 components/cache/adapters/apcu_adapter.rst    |    4 +-
 .../adapters/couchbasebucket_adapter.rst      |    2 +-
 .../adapters/couchbasecollection_adapter.rst  |    2 +-
 .../cache/adapters/filesystem_adapter.rst     |    2 +-
 .../cache/adapters/memcached_adapter.rst      |    4 +-
 .../cache/adapters/php_files_adapter.rst      |    2 +-
 components/cache/adapters/redis_adapter.rst   |   84 +-
 components/clock.rst                          |    6 +-
 components/config/definition.rst              |   24 +-
 .../console/changing_default_command.rst      |    2 +-
 components/console/events.rst                 |    2 +-
 .../console/helpers/formatterhelper.rst       |   14 +-
 components/console/helpers/progressbar.rst    |    2 +-
 components/console/helpers/questionhelper.rst |    6 +-
 components/event_dispatcher.rst               |    6 +-
 components/expression_language.rst            |    8 +-
 components/finder.rst                         |    2 +-
 components/form.rst                           |    2 +-
 components/http_foundation.rst                |   25 +-
 components/http_kernel.rst                    |    2 +-
 components/ldap.rst                           |    2 +-
 components/lock.rst                           |   38 +-
 components/options_resolver.rst               |    4 +-
 components/phpunit_bridge.rst                 |    4 +-
 components/process.rst                        |    4 +-
 components/property_access.rst                |    8 +-
 components/property_info.rst                  |   17 +-
 components/runtime.rst                        |    5 +-
 components/serializer.rst                     | 1938 --------------
 components/type_info.rst                      |  136 +-
 components/uid.rst                            |    4 +-
 components/validator/resources.rst            |    2 +-
 components/yaml.rst                           |   10 +
 configuration.rst                             |    8 +-
 configuration/env_var_processors.rst          |    2 +-
 configuration/micro_kernel_trait.rst          |    2 +-
 configuration/multiple_kernels.rst            |    2 +-
 configuration/override_dir_structure.rst      |    2 +-
 console.rst                                   |   10 +-
 console/calling_commands.rst                  |    5 +-
 console/command_in_controller.rst             |    2 +-
 console/commands_as_services.rst              |    4 +-
 console/input.rst                             |    2 +-
 contributing/code/bc.rst                      |    8 +-
 contributing/code/bugs.rst                    |    2 +-
 contributing/code/maintenance.rst             |    3 +
 contributing/documentation/format.rst         |    2 +-
 contributing/documentation/standards.rst      |    2 +-
 controller.rst                                |   32 +-
 controller/error_pages.rst                    |    2 +-
 deployment.rst                                |    2 +-
 deployment/proxies.rst                        |    2 +-
 doctrine.rst                                  |    8 +-
 doctrine/custom_dql_functions.rst             |    2 +-
 doctrine/multiple_entity_managers.rst         |    6 +-
 event_dispatcher.rst                          |   11 +
 form/bootstrap5.rst                           |    6 +-
 form/create_custom_field_type.rst             |    2 +-
 form/data_mappers.rst                         |    4 +-
 form/data_transformers.rst                    |    6 +-
 form/direct_submit.rst                        |    2 +-
 form/events.rst                               |    4 +-
 form/form_collections.rst                     |    6 +-
 form/form_customization.rst                   |    4 +-
 form/form_themes.rst                          |    2 +-
 form/inherit_data_option.rst                  |    2 +-
 form/type_guesser.rst                         |    2 +-
 form/unit_testing.rst                         |    6 +-
 form/without_class.rst                        |    2 +-
 forms.rst                                     |    2 +-
 frontend.rst                                  |   10 +
 frontend/asset_mapper.rst                     |  129 +-
 frontend/encore/installation.rst              |    2 +-
 frontend/encore/simple-example.rst            |    4 +-
 frontend/encore/virtual-machine.rst           |    4 +-
 http_cache/cache_invalidation.rst             |    2 +-
 http_cache/esi.rst                            |    2 +-
 http_cache/varnish.rst                        |   33 +-
 http_client.rst                               |   18 +-
 lock.rst                                      |    2 +-
 logging/channels_handlers.rst                 |    2 +-
 logging/monolog_exclude_http_codes.rst        |    2 +-
 mailer.rst                                    |   62 +-
 mercure.rst                                   |   93 +-
 messenger.rst                                 |   29 +-
 notifier.rst                                  |   85 +-
 profiler.rst                                  |    4 +-
 reference/attributes.rst                      |   12 +-
 reference/configuration/framework.rst         |   11 +-
 reference/configuration/web_profiler.rst      |    2 +-
 reference/constraints/Bic.rst                 |   15 +-
 reference/constraints/Callback.rst            |    8 +-
 reference/constraints/DateTime.rst            |   17 +-
 reference/constraints/EqualTo.rst             |    2 +-
 reference/constraints/File.rst                |    9 +-
 reference/constraints/IdenticalTo.rst         |    2 +-
 reference/constraints/Image.rst               |   20 +
 reference/constraints/MacAddress.rst          |    1 +
 reference/constraints/NotEqualTo.rst          |    2 +-
 reference/constraints/NotIdenticalTo.rst      |    2 +-
 reference/constraints/PasswordStrength.rst    |    6 +-
 reference/constraints/Slug.rst                |  119 +
 reference/constraints/UniqueEntity.rst        |    6 +-
 reference/constraints/_payload-option.rst.inc |    2 -
 reference/constraints/map.rst.inc             |    1 +
 reference/dic_tags.rst                        |    4 +-
 reference/formats/expression_language.rst     |    2 +-
 reference/formats/message_format.rst          |    2 +-
 reference/forms/types/choice.rst              |    2 +-
 reference/forms/types/collection.rst          |    6 +-
 reference/forms/types/country.rst             |    2 +-
 reference/forms/types/currency.rst            |    2 +-
 reference/forms/types/date.rst                |    9 +-
 reference/forms/types/dateinterval.rst        |    4 +-
 reference/forms/types/entity.rst              |    2 +-
 reference/forms/types/language.rst            |    2 +-
 reference/forms/types/locale.rst              |    2 +-
 reference/forms/types/money.rst               |    5 +-
 .../types/options/_date_limitation.rst.inc    |    2 +-
 .../forms/types/options/choice_lazy.rst.inc   |    2 +-
 .../forms/types/options/choice_name.rst.inc   |    2 +-
 reference/forms/types/options/data.rst.inc    |    2 +-
 .../options/empty_data_description.rst.inc    |    2 +-
 .../forms/types/options/inherit_data.rst.inc  |    2 +-
 reference/forms/types/options/value.rst.inc   |    2 +-
 reference/forms/types/password.rst            |    2 +-
 reference/forms/types/textarea.rst            |    2 +-
 reference/forms/types/time.rst                |   10 +-
 reference/forms/types/timezone.rst            |    2 +-
 reference/forms/types/url.rst                 |    7 +
 reference/twig_reference.rst                  |   33 +-
 routing.rst                                   |   78 +-
 scheduler.rst                                 |    8 +
 security.rst                                  |   37 +-
 security/access_control.rst                   |    6 +-
 security/access_token.rst                     |    4 +-
 security/custom_authenticator.rst             |   27 +-
 security/impersonating_user.rst               |    9 +-
 security/ldap.rst                             |    4 +-
 security/login_link.rst                       |    2 +-
 security/passwords.rst                        |    2 +-
 security/remember_me.rst                      |   25 +-
 security/user_providers.rst                   |    2 +-
 security/voters.rst                           |   31 +-
 serializer.rst                                | 2331 ++++++++++++++---
 serializer/custom_context_builders.rst        |    8 +-
 serializer/custom_encoders.rst                |   61 -
 serializer/custom_name_converter.rst          |  112 +
 serializer/custom_normalizer.rst              |   66 +-
 serializer/encoders.rst                       |  373 +++
 service_container.rst                         |    4 +-
 service_container/compiler_passes.rst         |   80 +-
 service_container/definitions.rst             |    4 +-
 service_container/lazy_services.rst           |    2 +-
 service_container/service_decoration.rst      |   76 +-
 .../service_subscribers_locators.rst          |    2 +-
 service_container/tags.rst                    |   17 +-
 session.rst                                   |   26 +-
 setup.rst                                     |    8 +-
 setup/_update_all_packages.rst.inc            |    2 +-
 setup/file_permissions.rst                    |    8 +-
 setup/symfony_server.rst                      |    8 +-
 setup/upgrade_major.rst                       |    2 +-
 setup/web_server_configuration.rst            |  110 +-
 string.rst                                    |   10 +-
 templates.rst                                 |    4 +-
 testing.rst                                   |   16 +-
 testing/end_to_end.rst                        |    2 +-
 testing/insulating_clients.rst                |    2 +-
 translation.rst                               |    8 +-
 validation.rst                                |    2 +-
 validation/custom_constraint.rst              |   41 +
 validation/groups.rst                         |    2 +-
 validation/sequence_provider.rst              |    4 +-
 web_link.rst                                  |   22 +-
 webhook.rst                                   |    7 +-
 workflow.rst                                  |    2 +-
 187 files changed, 4032 insertions(+), 3028 deletions(-)
 rename _images/{components => }/serializer/serializer_workflow.svg (100%)
 rename _images/sources/{components => }/serializer/serializer_workflow.dia (100%)
 delete mode 100644 components/serializer.rst
 create mode 100644 reference/constraints/Slug.rst
 delete mode 100644 serializer/custom_encoders.rst
 create mode 100644 serializer/custom_name_converter.rst
 create mode 100644 serializer/encoders.rst

diff --git a/.doctor-rst.yaml b/.doctor-rst.yaml
index 5ea86e6abc4..04e720bf653 100644
--- a/.doctor-rst.yaml
+++ b/.doctor-rst.yaml
@@ -23,6 +23,8 @@ rules:
     forbidden_directives:
         directives:
             - '.. index::'
+            - directive: '.. caution::'
+              replacements: ['.. warning::', '.. danger::']
     indention: ~
     lowercase_as_in_use_statements: ~
     max_blank_lines:
@@ -46,6 +48,7 @@ rules:
     no_namespace_after_use_statements: ~
     no_php_open_tag_in_code_block_php_directive: ~
     no_space_before_self_xml_closing_tag: ~
+    non_static_phpunit_assertions: ~
     only_backslashes_in_namespace_in_php_code_block: ~
     only_backslashes_in_use_statements_in_php_code_block: ~
     ordered_use_statements: ~
@@ -99,7 +102,6 @@ whitelist:
         - '#. The most important config file is ``app/config/services.yml``, which now is'
         - 'The bin/console Command'
         - '.. _`LDAP injection`: http://projects.webappsec.org/w/page/13246947/LDAP%20Injection'
-        - '.. versionadded:: 2.7.2' # Doctrine
         - '.. versionadded:: 2.8.0' # Doctrine
         - '.. versionadded:: 1.9.0' # Encore
         - '.. versionadded:: 1.18' # Flex in setup/upgrade_minor.rst
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index fcbdbe0477b..061b0bb85b0 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -73,7 +73,7 @@ jobs:
                     key: ${{ runner.os }}-doctor-rst-${{ steps.extract_base_branch.outputs.branch }}
 
             -   name: "Run DOCtor-RST"
-                uses: docker://oskarstark/doctor-rst:1.62.3
+                uses: docker://oskarstark/doctor-rst:1.64.0
                 with:
                     args: --short --error-format=github --cache-file=/github/workspace/.cache/doctor-rst.cache
 
diff --git a/_build/redirection_map b/_build/redirection_map
index 115ec75ade2..1701f4a8f70 100644
--- a/_build/redirection_map
+++ b/_build/redirection_map
@@ -525,8 +525,7 @@
 /testing/functional_tests_assertions /testing#testing-application-assertions
 /components https://symfony.com/components
 /components/index https://symfony.com/components
-/serializer/normalizers /components/serializer#normalizers
-/components/serializer#component-serializer-attributes-groups-annotations /components/serializer#component-serializer-attributes-groups-attributes
+/serializer/normalizers /serializer#serializer-built-in-normalizers
 /logging/monolog_regex_based_excludes /logging/monolog_exclude_http_codes
 /security/named_encoders /security/named_hashers
 /components/inflector /string#inflector
@@ -572,3 +571,5 @@
 /doctrine/registration_form /security#security-make-registration-form
 /form/form_dependencies /form/create_custom_field_type
 /doctrine/reverse_engineering /doctrine#doctrine-adding-mapping
+/components/serializer /serializer
+/serializer/custom_encoder /serializer/encoders#serializer-custom-encoder
diff --git a/_images/components/serializer/serializer_workflow.svg b/_images/serializer/serializer_workflow.svg
similarity index 100%
rename from _images/components/serializer/serializer_workflow.svg
rename to _images/serializer/serializer_workflow.svg
diff --git a/_images/sources/components/serializer/serializer_workflow.dia b/_images/sources/serializer/serializer_workflow.dia
similarity index 100%
rename from _images/sources/components/serializer/serializer_workflow.dia
rename to _images/sources/serializer/serializer_workflow.dia
diff --git a/bundles.rst b/bundles.rst
index ba3a2209999..878bee3af4a 100644
--- a/bundles.rst
+++ b/bundles.rst
@@ -3,7 +3,7 @@
 The Bundle System
 =================
 
-.. caution::
+.. warning::
 
     In Symfony versions prior to 4.0, it was recommended to organize your own
     application code using bundles. This is :ref:`no longer recommended <best-practice-no-application-bundles>` and bundles
@@ -58,7 +58,7 @@ Start by creating a new class called ``AcmeBlogBundle``::
     {
     }
 
-.. caution::
+.. warning::
 
     If your bundle must be compatible with previous Symfony versions you have to
     extend from the :class:`Symfony\\Component\\HttpKernel\\Bundle\\Bundle` instead.
@@ -118,7 +118,7 @@ to be adjusted if needed:
 
 .. _bundles-legacy-directory-structure:
 
-.. caution::
+.. warning::
 
     The recommended bundle structure was changed in Symfony 5, read the
     `Symfony 4.4 bundle documentation`_ for information about the old
diff --git a/bundles/best_practices.rst b/bundles/best_practices.rst
index 5996bcbe43d..376984388db 100644
--- a/bundles/best_practices.rst
+++ b/bundles/best_practices.rst
@@ -246,7 +246,7 @@ with Symfony Flex to install a specific Symfony version:
     # recommended to have a better output and faster download time)
     composer update --prefer-dist --no-progress
 
-.. caution::
+.. warning::
 
     If you want to cache your Composer dependencies, **do not** cache the
     ``vendor/`` directory as this has side-effects. Instead cache
diff --git a/bundles/extension.rst b/bundles/extension.rst
index 347f63b7af5..0537eb00c3e 100644
--- a/bundles/extension.rst
+++ b/bundles/extension.rst
@@ -200,7 +200,7 @@ Patterns are transformed into the actual class namespaces using the classmap
 generated by Composer. Therefore, before using these patterns, you must generate
 the full classmap executing the ``dump-autoload`` command of Composer.
 
-.. caution::
+.. warning::
 
     This technique can't be used when the classes to compile use the ``__DIR__``
     or ``__FILE__`` constants, because their values will change when loading
diff --git a/bundles/override.rst b/bundles/override.rst
index 36aea69b231..f25bd785373 100644
--- a/bundles/override.rst
+++ b/bundles/override.rst
@@ -19,7 +19,7 @@ For example, to override the ``templates/registration/confirmed.html.twig``
 template from the AcmeUserBundle, create this template:
 ``<your-project>/templates/bundles/AcmeUserBundle/registration/confirmed.html.twig``
 
-.. caution::
+.. warning::
 
     If you add a template in a new location, you *may* need to clear your
     cache (``php bin/console cache:clear``), even if you are in debug mode.
diff --git a/cache.rst b/cache.rst
index 7264585f233..833e4d77007 100644
--- a/cache.rst
+++ b/cache.rst
@@ -829,7 +829,7 @@ Then, register the ``SodiumMarshaller`` service using this key:
             //->addArgument(['env(base64:CACHE_DECRYPTION_KEY)', 'env(base64:OLD_CACHE_DECRYPTION_KEY)'])
             ->addArgument(new Reference('.inner'));
 
-.. caution::
+.. danger::
 
     This will encrypt the values of the cache items, but not the cache keys. Be
     careful not to leak sensitive data in the keys.
diff --git a/components/cache/adapters/apcu_adapter.rst b/components/cache/adapters/apcu_adapter.rst
index 99d76ce5d27..f2e92850cd8 100644
--- a/components/cache/adapters/apcu_adapter.rst
+++ b/components/cache/adapters/apcu_adapter.rst
@@ -5,7 +5,7 @@ This adapter is a high-performance, shared memory cache. It can *significantly*
 increase an application's performance, as its cache contents are stored in shared
 memory, a component appreciably faster than many others, such as the filesystem.
 
-.. caution::
+.. warning::
 
     **Requirement:** The `APCu extension`_ must be installed and active to use
     this adapter.
@@ -30,7 +30,7 @@ and cache items version string as constructor arguments::
         $version = null
     );
 
-.. caution::
+.. warning::
 
     Use of this adapter is discouraged in write/delete heavy workloads, as these
     operations cause memory fragmentation that results in significantly degraded performance.
diff --git a/components/cache/adapters/couchbasebucket_adapter.rst b/components/cache/adapters/couchbasebucket_adapter.rst
index aaf400319f4..29c9e26f83c 100644
--- a/components/cache/adapters/couchbasebucket_adapter.rst
+++ b/components/cache/adapters/couchbasebucket_adapter.rst
@@ -14,7 +14,7 @@ shared memory; you can store contents independent of your PHP environment.
 The ability to utilize a cluster of servers to provide redundancy and/or fail-over
 is also available.
 
-.. caution::
+.. warning::
 
     **Requirements:** The `Couchbase PHP extension`_ as well as a `Couchbase server`_
     must be installed, active, and running to use this adapter. Version ``2.6`` or
diff --git a/components/cache/adapters/couchbasecollection_adapter.rst b/components/cache/adapters/couchbasecollection_adapter.rst
index 25640a20b0f..ba78cc46eff 100644
--- a/components/cache/adapters/couchbasecollection_adapter.rst
+++ b/components/cache/adapters/couchbasecollection_adapter.rst
@@ -8,7 +8,7 @@ shared memory; you can store contents independent of your PHP environment.
 The ability to utilize a cluster of servers to provide redundancy and/or fail-over
 is also available.
 
-.. caution::
+.. warning::
 
     **Requirements:** The `Couchbase PHP extension`_ as well as a `Couchbase server`_
     must be installed, active, and running to use this adapter. Version ``3.0`` or
diff --git a/components/cache/adapters/filesystem_adapter.rst b/components/cache/adapters/filesystem_adapter.rst
index 26ef48af27c..db877454859 100644
--- a/components/cache/adapters/filesystem_adapter.rst
+++ b/components/cache/adapters/filesystem_adapter.rst
@@ -33,7 +33,7 @@ and cache root path as constructor parameters::
         $directory = null
     );
 
-.. caution::
+.. warning::
 
     The overhead of filesystem IO often makes this adapter one of the *slower*
     choices. If throughput is paramount, the in-memory adapters
diff --git a/components/cache/adapters/memcached_adapter.rst b/components/cache/adapters/memcached_adapter.rst
index d68d3e3b9ac..64baf0d4702 100644
--- a/components/cache/adapters/memcached_adapter.rst
+++ b/components/cache/adapters/memcached_adapter.rst
@@ -8,7 +8,7 @@ shared memory; you can store contents independent of your PHP environment.
 The ability to utilize a cluster of servers to provide redundancy and/or fail-over
 is also available.
 
-.. caution::
+.. warning::
 
     **Requirements:** The `Memcached PHP extension`_ as well as a `Memcached server`_
     must be installed, active, and running to use this adapter. Version ``2.2`` or
@@ -256,7 +256,7 @@ Available Options
     executed in a "fire-and-forget" manner; no attempt to ensure the operation
     has been received or acted on will be made once the client has executed it.
 
-    .. caution::
+    .. warning::
 
         Not all library operations are tested in this mode. Mixed TCP and UDP
         servers are not allowed.
diff --git a/components/cache/adapters/php_files_adapter.rst b/components/cache/adapters/php_files_adapter.rst
index efd2cf0e964..6f171f0fede 100644
--- a/components/cache/adapters/php_files_adapter.rst
+++ b/components/cache/adapters/php_files_adapter.rst
@@ -28,7 +28,7 @@ file similar to the following::
     handles file includes, this adapter has the potential to be much faster than other
     filesystem-based caches.
 
-.. caution::
+.. warning::
 
     While it supports updates and because it is using OPcache as a backend, this adapter is
     better suited for append-mostly needs. Using it in other scenarios might lead to
diff --git a/components/cache/adapters/redis_adapter.rst b/components/cache/adapters/redis_adapter.rst
index 719d6056f19..3362f4cc2db 100644
--- a/components/cache/adapters/redis_adapter.rst
+++ b/components/cache/adapters/redis_adapter.rst
@@ -15,7 +15,7 @@ Unlike the :doc:`APCu adapter </components/cache/adapters/apcu_adapter>`, and si
 shared memory; you can store contents independent of your PHP environment. The ability
 to utilize a cluster of servers to provide redundancy and/or fail-over is also available.
 
-.. caution::
+.. warning::
 
     **Requirements:** At least one `Redis server`_ must be installed and running to use this
     adapter. Additionally, this adapter requires a compatible extension or library that implements
@@ -38,7 +38,13 @@ as the second and third parameters::
         // the default lifetime (in seconds) for cache items that do not define their
         // own lifetime, with a value 0 causing items to be stored indefinitely (i.e.
         // until RedisAdapter::clear() is invoked or the server(s) are purged)
-        $defaultLifetime = 0
+        $defaultLifetime = 0,
+
+        // $marshaller (optional) An instance of MarshallerInterface to control the serialization
+        // and deserialization of cache items. By default, native PHP serialization is used.
+        // This can be useful for compressing data, applying custom serialization logic, or
+        // optimizing the size and performance of cached items
+        ?MarshallerInterface $marshaller = null
     );
 
 Configure the Connection
@@ -266,6 +272,80 @@ performance when using tag-based invalidation::
 
 Read more about this topic in the official `Redis LRU Cache Documentation`_.
 
+Working with Marshaller
+-----------------------
+
+TagAwareMarshaller for Tag-Based Caching
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Optimizes caching for tag-based retrieval, allowing efficient management of related items::
+
+    $marshaller = new TagAwareMarshaller();
+
+    $cache = new RedisAdapter($redis, 'tagged_namespace', 3600, $marshaller);
+
+    $item = $cache->getItem('tagged_key');
+    $item->set(['value' => 'some_data', 'tags' => ['tag1', 'tag2']]);
+    $cache->save($item);
+
+SodiumMarshaller for Encrypted Caching
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Encrypts cached data using Sodium for enhanced security::
+
+    $encryptionKeys = [sodium_crypto_box_keypair()];
+    $marshaller = new SodiumMarshaller($encryptionKeys);
+
+    $cache = new RedisAdapter($redis, 'secure_namespace', 3600, $marshaller);
+
+    $item = $cache->getItem('secure_key');
+    $item->set('confidential_data');
+    $cache->save($item);
+
+DefaultMarshaller with igbinary Serialization
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Uses ``igbinary` for faster and more efficient serialization when available::
+
+    $marshaller = new DefaultMarshaller(true);
+
+    $cache = new RedisAdapter($redis, 'optimized_namespace', 3600, $marshaller);
+
+    $item = $cache->getItem('optimized_key');
+    $item->set(['data' => 'optimized_data']);
+    $cache->save($item);
+
+DefaultMarshaller with Exception on Failure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Throws an exception if serialization fails, facilitating error handling::
+
+    $marshaller = new DefaultMarshaller(false, true);
+
+    $cache = new RedisAdapter($redis, 'error_namespace', 3600, $marshaller);
+
+    try {
+        $item = $cache->getItem('error_key');
+        $item->set('data');
+        $cache->save($item);
+    } catch (\ValueError $e) {
+        echo 'Serialization failed: '.$e->getMessage();
+    }
+
+SodiumMarshaller with Key Rotation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Supports key rotation, ensuring secure decryption with both old and new keys::
+
+    $keys = [sodium_crypto_box_keypair(), sodium_crypto_box_keypair()];
+    $marshaller = new SodiumMarshaller($keys);
+
+    $cache = new RedisAdapter($redis, 'rotated_namespace', 3600, $marshaller);
+
+    $item = $cache->getItem('rotated_key');
+    $item->set('data_to_encrypt');
+    $cache->save($item);
+
 .. _`Data Source Name (DSN)`: https://en.wikipedia.org/wiki/Data_source_name
 .. _`Redis server`: https://redis.io/
 .. _`Redis`: https://github.com/phpredis/phpredis
diff --git a/components/clock.rst b/components/clock.rst
index cdbbdd56e6b..5b20e6000b9 100644
--- a/components/clock.rst
+++ b/components/clock.rst
@@ -129,18 +129,18 @@ is expired or not, by modifying the clock's time::
             $validUntil = new DateTimeImmutable('2022-11-16 15:25:00');
 
             // $validUntil is in the future, so it is not expired
-            static::assertFalse($expirationChecker->isExpired($validUntil));
+            $this->assertFalse($expirationChecker->isExpired($validUntil));
 
             // Clock sleeps for 10 minutes, so now is '2022-11-16 15:30:00'
             $clock->sleep(600); // Instantly changes time as if we waited for 10 minutes (600 seconds)
 
             // modify the clock, accepts all formats supported by DateTimeImmutable::modify()
-            static::assertTrue($expirationChecker->isExpired($validUntil));
+            $this->assertTrue($expirationChecker->isExpired($validUntil));
 
             $clock->modify('2022-11-16 15:00:00');
 
             // $validUntil is in the future again, so it is no longer expired
-            static::assertFalse($expirationChecker->isExpired($validUntil));
+            $this->assertFalse($expirationChecker->isExpired($validUntil));
         }
     }
 
diff --git a/components/config/definition.rst b/components/config/definition.rst
index 929246fa915..24c142ec5a5 100644
--- a/components/config/definition.rst
+++ b/components/config/definition.rst
@@ -83,9 +83,19 @@ reflect the real structure of the configuration values::
             ->scalarNode('default_connection')
                 ->defaultValue('mysql')
             ->end()
+            ->stringNode('username')
+                ->defaultValue('root')
+            ->end()
+            ->stringNode('password')
+                ->defaultValue('root')
+            ->end()
         ->end()
     ;
 
+.. versionadded:: 7.2
+
+    The ``stringNode()`` method was introduced in Symfony 7.2.
+
 The root node itself is an array node, and has children, like the boolean
 node ``auto_connect`` and the scalar node ``default_connection``. In general:
 after defining a node, a call to ``end()`` takes you one step up in the
@@ -100,6 +110,7 @@ node definition. Node types are available for:
 * scalar (generic type that includes booleans, strings, integers, floats
   and ``null``)
 * boolean
+* string
 * integer
 * float
 * enum (similar to scalar, but it only allows a finite set of values)
@@ -109,6 +120,10 @@ node definition. Node types are available for:
 and are created with ``node($name, $type)`` or their associated shortcut
 ``xxxxNode($name)`` method.
 
+.. versionadded:: 7.2
+
+    Support for the ``string`` type was introduced in Symfony 7.2.
+
 Numeric Node Constraints
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -670,7 +685,7 @@ The separator used in keys is typically ``_`` in YAML and ``-`` in XML.
 For example, ``auto_connect`` in YAML and ``auto-connect`` in XML. The
 normalization would make both of these ``auto_connect``.
 
-.. caution::
+.. warning::
 
     The target key will not be altered if it's mixed like
     ``foo-bar_moo`` or if it already exists.
@@ -800,6 +815,7 @@ A validation rule always has an "if" part. You can specify this part in
 the following ways:
 
 - ``ifTrue()``
+- ``ifFalse()``
 - ``ifString()``
 - ``ifNull()``
 - ``ifEmpty()``
@@ -818,6 +834,10 @@ A validation rule also requires a "then" part:
 Usually, "then" is a closure. Its return value will be used as a new value
 for the node, instead of the node's original value.
 
+.. versionadded:: 7.3
+
+    The ``ifFalse()`` method was introduced in Symfony 7.3.
+
 Configuring the Node Path Separator
 -----------------------------------
 
@@ -889,7 +909,7 @@ Otherwise the result is a clean array of configuration values::
         $configs
     );
 
-.. caution::
+.. warning::
 
     When processing the configuration tree, the processor assumes that the top
     level array key (which matches the extension name) is already stripped off.
diff --git a/components/console/changing_default_command.rst b/components/console/changing_default_command.rst
index b739e3b39ba..c69995ea395 100644
--- a/components/console/changing_default_command.rst
+++ b/components/console/changing_default_command.rst
@@ -52,7 +52,7 @@ This will print the following to the command line:
 
     Hello World
 
-.. caution::
+.. warning::
 
     This feature has a limitation: you cannot pass any argument or option to
     the default command because they are ignored.
diff --git a/components/console/events.rst b/components/console/events.rst
index f0edf2205ac..e550025b7dd 100644
--- a/components/console/events.rst
+++ b/components/console/events.rst
@@ -14,7 +14,7 @@ the wheel, it uses the Symfony EventDispatcher component to do the work::
     $application->setDispatcher($dispatcher);
     $application->run();
 
-.. caution::
+.. warning::
 
     Console events are only triggered by the main command being executed.
     Commands called by the main command will not trigger any event, unless
diff --git a/components/console/helpers/formatterhelper.rst b/components/console/helpers/formatterhelper.rst
index 3cb87c4c307..d2b19915a3a 100644
--- a/components/console/helpers/formatterhelper.rst
+++ b/components/console/helpers/formatterhelper.rst
@@ -129,10 +129,16 @@ Sometimes you want to format seconds to time. This is possible with the
 The first argument is the seconds to format and the second argument is the
 precision (default ``1``) of the result::
 
-    Helper::formatTime(42);        // 42 secs
-    Helper::formatTime(125);       // 2 mins
-    Helper::formatTime(125, 2);    // 2 mins, 5 secs
-    Helper::formatTime(172799, 4); // 1 day, 23 hrs, 59 mins, 59 secs
+    Helper::formatTime(0.001);         // 1 ms
+    Helper::formatTime(42);            // 42 s
+    Helper::formatTime(125);           // 2 min
+    Helper::formatTime(125, 2);        // 2 min, 5 s
+    Helper::formatTime(172799, 4);     // 1 d, 23 h, 59 min, 59 s
+    Helper::formatTime(172799.056, 5); // 1 d, 23 h, 59 min, 59 s, 56 ms
+
+.. versionadded:: 7.3
+
+    Support for formatting up to milliseconds was introduced in Symfony 7.3.
 
 Formatting Memory
 -----------------
diff --git a/components/console/helpers/progressbar.rst b/components/console/helpers/progressbar.rst
index 4d524a2008e..19e2d0daef5 100644
--- a/components/console/helpers/progressbar.rst
+++ b/components/console/helpers/progressbar.rst
@@ -323,7 +323,7 @@ to display it can be customized::
     // the bar width
     $progressBar->setBarWidth(50);
 
-.. caution::
+.. warning::
 
     For performance reasons, Symfony redraws the screen once every 100ms. If this is too
     fast or too slow for your application, use the methods
diff --git a/components/console/helpers/questionhelper.rst b/components/console/helpers/questionhelper.rst
index e33c4ed5fa7..2670ec3084a 100644
--- a/components/console/helpers/questionhelper.rst
+++ b/components/console/helpers/questionhelper.rst
@@ -329,7 +329,7 @@ convenient for passwords::
         return Command::SUCCESS;
     }
 
-.. caution::
+.. warning::
 
     When you ask for a hidden response, Symfony will use either a binary, change
     ``stty`` mode or use another trick to hide the response. If none is available,
@@ -392,7 +392,7 @@ method::
         return Command::SUCCESS;
     }
 
-.. caution::
+.. warning::
 
     The normalizer is called first and the returned value is used as the input
     of the validator. If the answer is invalid, don't throw exceptions in the
@@ -540,7 +540,7 @@ This way you can test any user interaction (even complex ones) by passing the ap
     simulates a user hitting ``ENTER`` after each input, no need for passing
     an additional input.
 
-.. caution::
+.. warning::
 
     On Windows systems Symfony uses a special binary to implement hidden
     questions. This means that those questions don't use the default ``Input``
diff --git a/components/event_dispatcher.rst b/components/event_dispatcher.rst
index 83cead3d19c..8cd676dd5fe 100644
--- a/components/event_dispatcher.rst
+++ b/components/event_dispatcher.rst
@@ -476,11 +476,7 @@ with some other dispatchers:
 Learn More
 ----------
 
-.. toctree::
-    :maxdepth: 1
-
-    /components/event_dispatcher/generic_event
-
+* :doc:`/components/event_dispatcher/generic_event`
 * :ref:`The kernel.event_listener tag <dic-tags-kernel-event-listener>`
 * :ref:`The kernel.event_subscriber tag <dic-tags-kernel-event-subscriber>`
 
diff --git a/components/expression_language.rst b/components/expression_language.rst
index 785beebd9da..b0dd10b0f42 100644
--- a/components/expression_language.rst
+++ b/components/expression_language.rst
@@ -106,6 +106,10 @@ if the expression is not valid::
 
     $expressionLanguage->lint('1 + 2', []); // doesn't throw anything
 
+    $expressionLanguage->lint('1 + a', []);
+    // throws a SyntaxError exception:
+    // "Variable "a" is not valid around position 5 for expression `1 + a`."
+
 The behavior of these methods can be configured with some flags defined in the
 :class:`Symfony\\Component\\ExpressionLanguage\\Parser` class:
 
@@ -121,8 +125,8 @@ This is how you can use these flags::
 
     $expressionLanguage = new ExpressionLanguage();
 
-    // this returns true because the unknown variables and functions are ignored
-    var_dump($expressionLanguage->lint('unknown_var + unknown_function()', Parser::IGNORE_UNKNOWN_VARIABLES | Parser::IGNORE_UNKNOWN_FUNCTIONS));
+    // does not throw a SyntaxError because the unknown variables and functions are ignored
+    $expressionLanguage->lint('unknown_var + unknown_function()', [], Parser::IGNORE_UNKNOWN_VARIABLES | Parser::IGNORE_UNKNOWN_FUNCTIONS);
 
 .. versionadded:: 7.1
 
diff --git a/components/finder.rst b/components/finder.rst
index a3b91470b62..cecc597ac64 100644
--- a/components/finder.rst
+++ b/components/finder.rst
@@ -41,7 +41,7 @@ The ``$file`` variable is an instance of
 :class:`Symfony\\Component\\Finder\\SplFileInfo` which extends PHP's own
 :phpclass:`SplFileInfo` to provide methods to work with relative paths.
 
-.. caution::
+.. warning::
 
     The ``Finder`` object doesn't reset its internal state automatically.
     This means that you need to create a new instance if you do not want
diff --git a/components/form.rst b/components/form.rst
index f463ef5911b..44f407e4c8e 100644
--- a/components/form.rst
+++ b/components/form.rst
@@ -644,7 +644,7 @@ method:
 
         // ...
 
-.. caution::
+.. warning::
 
     The form's ``createView()`` method should be called *after* ``handleRequest()`` is
     called. Otherwise, when using :doc:`form events </form/events>`, changes done
diff --git a/components/http_foundation.rst b/components/http_foundation.rst
index 4dcf3b1e4da..8db6cd27f68 100644
--- a/components/http_foundation.rst
+++ b/components/http_foundation.rst
@@ -367,11 +367,13 @@ of the ``anonymize()`` method to specify the number of bytes that should be
 anonymized depending on the IP address format::
 
     $ipv4 = '123.234.235.236';
-    $anonymousIpv4 = IpUtils::anonymize($ipv4, v4Bytes: 3);
+    $anonymousIpv4 = IpUtils::anonymize($ipv4, 3);
     // $anonymousIpv4 = '123.0.0.0'
 
     $ipv6 = '2a01:198:603:10:396e:4789:8e99:890f';
-    $anonymousIpv6 = IpUtils::anonymize($ipv6, v6Bytes: 10);
+    // (you must define the second argument (bytes to anonymize in IPv4 addresses)
+    // even when you are only anonymizing IPv6 addresses)
+    $anonymousIpv6 = IpUtils::anonymize($ipv6, 3, 10);
     // $anonymousIpv6 = '2a01:198:603::'
 
 .. versionadded:: 7.2
@@ -679,8 +681,19 @@ Streaming a Response
 ~~~~~~~~~~~~~~~~~~~~
 
 The :class:`Symfony\\Component\\HttpFoundation\\StreamedResponse` class allows
-you to stream the Response back to the client. The response content is
-represented by a PHP callable instead of a string::
+you to stream the Response back to the client. The response content can be
+represented by a string iterable::
+
+    use Symfony\Component\HttpFoundation\StreamedResponse;
+
+    $chunks = ['Hello', ' World'];
+
+    $response = new StreamedResponse();
+    $response->setChunks($chunks);
+    $response->send();
+
+For most complex use cases, the response content can be instead represented by
+a PHP callable::
 
     use Symfony\Component\HttpFoundation\StreamedResponse;
 
@@ -708,6 +721,10 @@ represented by a PHP callable instead of a string::
         // disables FastCGI buffering in nginx only for this response
         $response->headers->set('X-Accel-Buffering', 'no');
 
+.. versionadded:: 7.3
+
+    Support for using string iterables was introduced in Symfony 7.3.
+
 Streaming a JSON Response
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/components/http_kernel.rst b/components/http_kernel.rst
index 97de70b66df..02791b370bc 100644
--- a/components/http_kernel.rst
+++ b/components/http_kernel.rst
@@ -471,7 +471,7 @@ you will trigger the ``kernel.terminate`` event where you can perform certain
 actions that you may have delayed in order to return the response as quickly
 as possible to the client (e.g. sending emails).
 
-.. caution::
+.. warning::
 
     Internally, the HttpKernel makes use of the :phpfunction:`fastcgi_finish_request`
     PHP function. This means that at the moment, only the `PHP FPM`_ server
diff --git a/components/ldap.rst b/components/ldap.rst
index d5f6bc3fdfe..e52a341986c 100644
--- a/components/ldap.rst
+++ b/components/ldap.rst
@@ -70,7 +70,7 @@ distinguished name (DN) and the password of a user::
 
     $ldap->bind($dn, $password);
 
-.. caution::
+.. danger::
 
     When the LDAP server allows unauthenticated binds, a blank password will always be valid.
 
diff --git a/components/lock.rst b/components/lock.rst
index bf75fb49f7a..b8ba38c8fc7 100644
--- a/components/lock.rst
+++ b/components/lock.rst
@@ -359,7 +359,7 @@ lose the lock it acquired automatically::
         throw new \Exception('Process failed');
     }
 
-.. caution::
+.. warning::
 
     A common pitfall might be to use the ``isAcquired()`` method to check if
     a lock has already been acquired by any process. As you can see in this example
@@ -427,7 +427,7 @@ when the PHP process ends)::
     // if none is given, sys_get_temp_dir() is used internally.
     $store = new FlockStore('/var/stores');
 
-.. caution::
+.. warning::
 
     Beware that some file systems (such as some types of NFS) do not support
     locking. In those cases, it's better to use a directory on a local disk
@@ -668,7 +668,7 @@ the stores::
 
     $store = new CombinedStore($stores, new UnanimousStrategy());
 
-.. caution::
+.. warning::
 
     In order to get high availability when using the ``ConsensusStrategy``, the
     minimum cluster size must be three servers. This allows the cluster to keep
@@ -720,7 +720,7 @@ the ``Lock``.
 Every concurrent process must store the ``Lock`` on the same server. Otherwise two
 different machines may allow two different processes to acquire the same ``Lock``.
 
-.. caution::
+.. warning::
 
     To guarantee that the same server will always be safe, do not use Memcached
     behind a LoadBalancer, a cluster or round-robin DNS. Even if the main server
@@ -762,12 +762,12 @@ Using the above methods, a robust code would be::
         // Perform the task whose duration MUST be less than 5 seconds
     }
 
-.. caution::
+.. warning::
 
     Choose wisely the lifetime of the ``Lock`` and check whether its remaining
     time to live is enough to perform the task.
 
-.. caution::
+.. warning::
 
     Storing a ``Lock`` usually takes a few milliseconds, but network conditions
     may increase that time a lot (up to a few seconds). Take that into account
@@ -776,7 +776,7 @@ Using the above methods, a robust code would be::
 By design, locks are stored on servers with a defined lifetime. If the date or
 time of the machine changes, a lock could be released sooner than expected.
 
-.. caution::
+.. warning::
 
     To guarantee that date won't change, the NTP service should be disabled
     and the date should be updated when the service is stopped.
@@ -798,7 +798,7 @@ deployments.
 
 Some file systems (such as some types of NFS) do not support locking.
 
-.. caution::
+.. warning::
 
     All concurrent processes must use the same physical file system by running
     on the same machine and using the same absolute path to the lock directory.
@@ -827,7 +827,7 @@ and may disappear by mistake at any time.
 If the Memcached service or the machine hosting it restarts, every lock would
 be lost without notifying the running processes.
 
-.. caution::
+.. warning::
 
     To avoid that someone else acquires a lock after a restart, it's recommended
     to delay service start and wait at least as long as the longest lock TTL.
@@ -835,7 +835,7 @@ be lost without notifying the running processes.
 By default Memcached uses a LRU mechanism to remove old entries when the service
 needs space to add new items.
 
-.. caution::
+.. warning::
 
     The number of items stored in Memcached must be under control. If it's not
     possible, LRU should be disabled and Lock should be stored in a dedicated
@@ -853,7 +853,7 @@ method uses the Memcached's ``flush()`` method which purges and removes everythi
 MongoDbStore
 ~~~~~~~~~~~~
 
-.. caution::
+.. warning::
 
     The locked resource name is indexed in the ``_id`` field of the lock
     collection. Beware that an indexed field's value in MongoDB can be
@@ -879,7 +879,7 @@ about `Expire Data from Collections by Setting TTL`_ in MongoDB.
     recommended to set constructor option ``gcProbability`` to ``0.0`` to
     disable this behavior if you have manually dealt with TTL index creation.
 
-.. caution::
+.. warning::
 
     This store relies on all PHP application and database nodes to have
     synchronized clocks for lock expiry to occur at the correct time. To ensure
@@ -896,12 +896,12 @@ PdoStore
 
 The PdoStore relies on the `ACID`_ properties of the SQL engine.
 
-.. caution::
+.. warning::
 
     In a cluster configured with multiple primaries, ensure writes are
     synchronously propagated to every node, or always use the same node.
 
-.. caution::
+.. warning::
 
     Some SQL engines like MySQL allow to disable the unique constraint check.
     Ensure that this is not the case ``SET unique_checks=1;``.
@@ -910,7 +910,7 @@ In order to purge old locks, this store uses a current datetime to define an
 expiration date reference. This mechanism relies on all server nodes to
 have synchronized clocks.
 
-.. caution::
+.. warning::
 
     To ensure locks don't expire prematurely; the TTLs should be set with
     enough extra time to account for any clock drift between nodes.
@@ -939,7 +939,7 @@ and may disappear by mistake at any time.
 If the Redis service or the machine hosting it restarts, every locks would
 be lost without notifying the running processes.
 
-.. caution::
+.. warning::
 
     To avoid that someone else acquires a lock after a restart, it's recommended
     to delay service start and wait at least as long as the longest lock TTL.
@@ -967,7 +967,7 @@ The ``CombinedStore`` will be, at best, as reliable as the least reliable of
 all managed stores. As soon as one managed store returns erroneous information,
 the ``CombinedStore`` won't be reliable.
 
-.. caution::
+.. warning::
 
     All concurrent processes must use the same configuration, with the same
     amount of managed stored and the same endpoint.
@@ -985,13 +985,13 @@ must run on the same machine, virtual machine or container. Be careful when
 updating a Kubernetes or Swarm service because for a short period of time, there
 can be two running containers in parallel.
 
-.. caution::
+.. warning::
 
     All concurrent processes must use the same machine. Before starting a
     concurrent process on a new machine, check that other processes are stopped
     on the old one.
 
-.. caution::
+.. warning::
 
     When running on systemd with non-system user and option ``RemoveIPC=yes``
     (default value), locks are deleted by systemd when that user logs out.
diff --git a/components/options_resolver.rst b/components/options_resolver.rst
index c8052d0d395..ff25f9e0fc4 100644
--- a/components/options_resolver.rst
+++ b/components/options_resolver.rst
@@ -485,7 +485,7 @@ these options, you can return the desired default value::
         }
     }
 
-.. caution::
+.. warning::
 
     The argument of the callable must be type hinted as ``Options``. Otherwise,
     the callable itself is considered as the default value of the option.
@@ -699,7 +699,7 @@ to the closure to access to them::
         }
     }
 
-.. caution::
+.. warning::
 
     The arguments of the closure must be type hinted as ``OptionsResolver`` and
     ``Options`` respectively. Otherwise, the closure itself is considered as the
diff --git a/components/phpunit_bridge.rst b/components/phpunit_bridge.rst
index ba37bc0ecda..5ce4c003a11 100644
--- a/components/phpunit_bridge.rst
+++ b/components/phpunit_bridge.rst
@@ -253,7 +253,7 @@ deprecations but:
 * forget to mark appropriate tests with the ``@group legacy`` annotations.
 
 By using ``SYMFONY_DEPRECATIONS_HELPER=max[self]=0``, deprecations that are
-triggered outside the ``vendors`` directory will be accounted for separately,
+triggered outside the ``vendor/`` directory will be accounted for separately,
 while deprecations triggered from a library inside it will not (unless you reach
 999999 of these), giving you the best of both worlds.
 
@@ -621,7 +621,7 @@ test::
 
 And that's all!
 
-.. caution::
+.. warning::
 
     Time-based function mocking follows the `PHP namespace resolutions rules`_
     so "fully qualified function calls" (e.g ``\time()``) cannot be mocked.
diff --git a/components/process.rst b/components/process.rst
index 9502665dde1..f6c8837d2c3 100644
--- a/components/process.rst
+++ b/components/process.rst
@@ -108,7 +108,7 @@ You can configure the options passed to the ``other_options`` argument of
     // this option allows a subprocess to continue running after the main script exited
     $process->setOptions(['create_new_console' => true]);
 
-.. caution::
+.. warning::
 
     Most of the options defined by ``proc_open()`` (such as ``create_new_console``
     and ``suppress_errors``) are only supported on Windows operating systems.
@@ -552,7 +552,7 @@ Use :method:`Symfony\\Component\\Process\\Process::disableOutput` and
     $process->disableOutput();
     $process->run();
 
-.. caution::
+.. warning::
 
     You cannot enable or disable the output while the process is running.
 
diff --git a/components/property_access.rst b/components/property_access.rst
index 600481dce1a..f608640fa9b 100644
--- a/components/property_access.rst
+++ b/components/property_access.rst
@@ -26,6 +26,8 @@ default configuration::
 
     $propertyAccessor = PropertyAccess::createPropertyAccessor();
 
+.. _property-access-reading-arrays:
+
 Reading from Arrays
 -------------------
 
@@ -112,7 +114,7 @@ To read from properties, use the "dot" notation::
 
     var_dump($propertyAccessor->getValue($person, 'children[0].firstName')); // 'Bar'
 
-.. caution::
+.. warning::
 
     Accessing public properties is the last option used by ``PropertyAccessor``.
     It tries to access the value using the below methods first before using
@@ -260,7 +262,7 @@ The ``getValue()`` method can also use the magic ``__get()`` method::
 
     var_dump($propertyAccessor->getValue($person, 'Wouter')); // [...]
 
-.. caution::
+.. warning::
 
     When implementing the magic ``__get()`` method, you also need to implement
     ``__isset()``.
@@ -301,7 +303,7 @@ enable this feature by using :class:`Symfony\\Component\\PropertyAccess\\Propert
 
     var_dump($propertyAccessor->getValue($person, 'wouter')); // [...]
 
-.. caution::
+.. warning::
 
     The ``__call()`` feature is disabled by default, you can enable it by calling
     :method:`Symfony\\Component\\PropertyAccess\\PropertyAccessorBuilder::enableMagicCall`
diff --git a/components/property_info.rst b/components/property_info.rst
index 892cd5345a3..0ff1768441a 100644
--- a/components/property_info.rst
+++ b/components/property_info.rst
@@ -469,7 +469,18 @@ information from annotations of properties and methods, such as ``@var``,
     use App\Domain\Foo;
 
     $phpStanExtractor = new PhpStanExtractor();
+
+    // Type information.
     $phpStanExtractor->getTypesFromConstructor(Foo::class, 'bar');
+    // Description information.
+    $phpStanExtractor->getShortDescription($class, 'bar');
+    $phpStanExtractor->getLongDescription($class, 'bar');
+
+.. versionadded:: 7.3
+
+    The :method:`Symfony\\Component\\PropertyInfo\\Extractor\\PhpStanExtractor::getShortDescription`
+    and :method:`Symfony\\Component\\PropertyInfo\\Extractor\\PhpStanExtractor::getLongDescription`
+    methods were introduced in Symfony 7.3.
 
 SerializerExtractor
 ~~~~~~~~~~~~~~~~~~~
@@ -478,9 +489,9 @@ SerializerExtractor
 
     This extractor depends on the `symfony/serializer`_ library.
 
-Using :ref:`groups metadata <serializer-using-serialization-groups-attributes>`
-from the :doc:`Serializer component </components/serializer>`,
-the :class:`Symfony\\Component\\PropertyInfo\\Extractor\\SerializerExtractor`
+Using :ref:`groups metadata <serializer-groups-attribute>` from the
+:doc:`Serializer component </serializer>`, the
+:class:`Symfony\\Component\\PropertyInfo\\Extractor\\SerializerExtractor`
 provides list information. This extractor is *not* registered automatically
 with the ``property_info`` service in the Symfony Framework::
 
diff --git a/components/runtime.rst b/components/runtime.rst
index 7d17e7e7456..4eb75de2a75 100644
--- a/components/runtime.rst
+++ b/components/runtime.rst
@@ -3,7 +3,7 @@ The Runtime Component
 
     The Runtime Component decouples the bootstrapping logic from any global state
     to make sure the application can run with runtimes like `PHP-PM`_, `ReactPHP`_,
-    `Swoole`_, etc. without any changes.
+    `Swoole`_, `FrankenPHP`_ etc. without any changes.
 
 Installation
 ------------
@@ -42,7 +42,7 @@ the component. This file runs the following logic:
 #. At last, the Runtime is used to run the application (i.e. calling
    ``$kernel->handle(Request::createFromGlobals())->send()``).
 
-.. caution::
+.. warning::
 
     If you use the Composer ``--no-plugins`` option, the ``autoload_runtime.php``
     file won't be created.
@@ -487,6 +487,7 @@ The end user will now be able to create front controller like::
 
 .. _PHP-PM: https://github.com/php-pm/php-pm
 .. _Swoole: https://openswoole.com/
+.. _FrankenPHP: https://frankenphp.dev/
 .. _ReactPHP: https://reactphp.org/
 .. _`PSR-15`: https://www.php-fig.org/psr/psr-15/
 .. _`runtime template file`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Runtime/Internal/autoload_runtime.template
diff --git a/components/serializer.rst b/components/serializer.rst
deleted file mode 100644
index 0764612e28a..00000000000
--- a/components/serializer.rst
+++ /dev/null
@@ -1,1938 +0,0 @@
-The Serializer Component
-========================
-
-    The Serializer component is meant to be used to turn objects into a
-    specific format (XML, JSON, YAML, ...) and the other way around.
-
-In order to do so, the Serializer component follows the following schema.
-
-.. raw:: html
-
-    <object data="../_images/components/serializer/serializer_workflow.svg" type="image/svg+xml"
-        alt="A flow diagram showing how objects are serialized/deserialized. This is described in the subsequent paragraph."
-    ></object>
-
-When (de)serializing objects, the Serializer uses an array as the intermediary
-between objects and serialized contents. Encoders will only deal with
-turning specific **formats** into **arrays** and vice versa. The same way,
-normalizers will deal with turning specific **objects** into **arrays** and
-vice versa. The Serializer deals with calling the normalizers and encoders
-when serializing objects or deserializing formats.
-
-Serialization is a complex topic. This component may not cover all your use
-cases out of the box, but it can be useful for developing tools to
-serialize and deserialize your objects.
-
-Installation
-------------
-
-.. code-block:: terminal
-
-    $ composer require symfony/serializer
-
-.. include:: /components/require_autoload.rst.inc
-
-To use the ``ObjectNormalizer``, the :doc:`PropertyAccess component </components/property_access>`
-must also be installed.
-
-Usage
------
-
-.. seealso::
-
-    This article explains the philosophy of the Serializer and gets you familiar
-    with the concepts of normalizers and encoders. The code examples assume
-    that you use the Serializer as an independent component. If you are using
-    the Serializer in a Symfony application, read :doc:`/serializer` after you
-    finish this article.
-
-To use the Serializer component, set up the
-:class:`Symfony\\Component\\Serializer\\Serializer` specifying which encoders
-and normalizer are going to be available::
-
-    use Symfony\Component\Serializer\Encoder\JsonEncoder;
-    use Symfony\Component\Serializer\Encoder\XmlEncoder;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    $encoders = [new XmlEncoder(), new JsonEncoder()];
-    $normalizers = [new ObjectNormalizer()];
-
-    $serializer = new Serializer($normalizers, $encoders);
-
-The preferred normalizer is the
-:class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer`,
-but other normalizers are available. All the examples shown below use
-the ``ObjectNormalizer``.
-
-Serializing an Object
----------------------
-
-For the sake of this example, assume the following class already
-exists in your project::
-
-    namespace App\Model;
-
-    class Person
-    {
-        private int $age;
-        private string $name;
-        private bool $sportsperson;
-        private ?\DateTimeInterface $createdAt;
-
-        // Getters
-        public function getAge(): int
-        {
-            return $this->age;
-        }
-
-        public function getName(): string
-        {
-            return $this->name;
-        }
-
-        public function getCreatedAt(): ?\DateTimeInterface
-        {
-            return $this->createdAt;
-        }
-
-        // Issers
-        public function isSportsperson(): bool
-        {
-            return $this->sportsperson;
-        }
-
-        // Setters
-        public function setAge(int $age): void
-        {
-            $this->age = $age;
-        }
-
-        public function setName(string $name): void
-        {
-            $this->name = $name;
-        }
-
-        public function setSportsperson(bool $sportsperson): void
-        {
-            $this->sportsperson = $sportsperson;
-        }
-
-        public function setCreatedAt(?\DateTimeInterface $createdAt = null): void
-        {
-            $this->createdAt = $createdAt;
-        }
-    }
-
-Now, if you want to serialize this object into JSON, you only need to
-use the Serializer service created before::
-
-    use App\Model\Person;
-
-    $person = new Person();
-    $person->setName('foo');
-    $person->setAge(99);
-    $person->setSportsperson(false);
-
-    $jsonContent = $serializer->serialize($person, 'json');
-
-    // $jsonContent contains {"name":"foo","age":99,"sportsperson":false,"createdAt":null}
-
-    echo $jsonContent; // or return it in a Response
-
-The first parameter of the :method:`Symfony\\Component\\Serializer\\Serializer::serialize`
-is the object to be serialized and the second is used to choose the proper encoder,
-in this case :class:`Symfony\\Component\\Serializer\\Encoder\\JsonEncoder`.
-
-Deserializing an Object
------------------------
-
-You'll now learn how to do the exact opposite. This time, the information
-of the ``Person`` class would be encoded in XML format::
-
-    use App\Model\Person;
-
-    $data = <<<EOF
-    <person>
-        <name>foo</name>
-        <age>99</age>
-        <sportsperson>false</sportsperson>
-    </person>
-    EOF;
-
-    $person = $serializer->deserialize($data, Person::class, 'xml');
-
-In this case, :method:`Symfony\\Component\\Serializer\\Serializer::deserialize`
-needs three parameters:
-
-#. The information to be decoded
-#. The name of the class this information will be decoded to
-#. The encoder used to convert that information into an array
-
-By default, additional attributes that are not mapped to the denormalized object
-will be ignored by the Serializer component. If you prefer to throw an exception
-when this happens, set the ``AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES`` context option to
-``false`` and provide an object that implements ``ClassMetadataFactoryInterface``
-when constructing the normalizer::
-
-    use App\Model\Person;
-
-    $data = <<<EOF
-    <person>
-        <name>foo</name>
-        <age>99</age>
-        <city>Paris</city>
-    </person>
-    EOF;
-
-    // $loader is any of the valid loaders explained later in this article
-    $classMetadataFactory = new ClassMetadataFactory($loader);
-    $normalizer = new ObjectNormalizer($classMetadataFactory);
-    $serializer = new Serializer([$normalizer]);
-
-    // this will throw a Symfony\Component\Serializer\Exception\ExtraAttributesException
-    // because "city" is not an attribute of the Person class
-    $person = $serializer->deserialize($data, Person::class, 'xml', [
-        AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
-    ]);
-
-Deserializing in an Existing Object
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The serializer can also be used to update an existing object::
-
-    // ...
-    $person = new Person();
-    $person->setName('bar');
-    $person->setAge(99);
-    $person->setSportsperson(true);
-
-    $data = <<<EOF
-    <person>
-        <name>foo</name>
-        <age>69</age>
-    </person>
-    EOF;
-
-    $serializer->deserialize($data, Person::class, 'xml', [AbstractNormalizer::OBJECT_TO_POPULATE => $person]);
-    // $person = App\Model\Person(name: 'foo', age: '69', sportsperson: true)
-
-This is a common need when working with an ORM.
-
-The ``AbstractNormalizer::OBJECT_TO_POPULATE`` is only used for the top level object. If that object
-is the root of a tree structure, all child elements that exist in the
-normalized data will be re-created with new instances.
-
-When the ``AbstractObjectNormalizer::DEEP_OBJECT_TO_POPULATE`` option is set to
-true, existing children of the root ``OBJECT_TO_POPULATE`` are updated from the
-normalized data, instead of the denormalizer re-creating them. Note that
-``DEEP_OBJECT_TO_POPULATE`` only works for single child objects, but not for
-arrays of objects. Those will still be replaced when present in the normalized
-data.
-
-Context
--------
-
-Many Serializer features can be configured :ref:`using a context <serializer_serializer-context>`.
-
-.. _component-serializer-attributes-groups:
-
-Attributes Groups
------------------
-
-Sometimes, you want to serialize different sets of attributes from your
-entities. Groups are a handy way to achieve this need.
-
-Assume you have the following plain-old-PHP object::
-
-    namespace Acme;
-
-    class MyObj
-    {
-        public string $foo;
-
-        private string $bar;
-
-        public function getBar(): string
-        {
-            return $this->bar;
-        }
-
-        public function setBar($bar): string
-        {
-            return $this->bar = $bar;
-        }
-    }
-
-The definition of serialization can be specified using attributes, XML or YAML.
-The :class:`Symfony\\Component\\Serializer\\Mapping\\Factory\\ClassMetadataFactory`
-that will be used by the normalizer must be aware of the format to use.
-
-The following code shows how to initialize the :class:`Symfony\\Component\\Serializer\\Mapping\\Factory\\ClassMetadataFactory`
-for each format:
-
-* Attributes in PHP files::
-
-    use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
-    use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader;
-
-    $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
-
-* YAML files::
-
-    use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
-    use Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader;
-
-    $classMetadataFactory = new ClassMetadataFactory(new YamlFileLoader('/path/to/your/definition.yaml'));
-
-* XML files::
-
-    use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
-    use Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader;
-
-    $classMetadataFactory = new ClassMetadataFactory(new XmlFileLoader('/path/to/your/definition.xml'));
-
-.. _component-serializer-attributes-groups-attributes:
-
-Then, create your groups definition:
-
-.. configuration-block::
-
-    .. code-block:: php-attributes
-
-        namespace Acme;
-
-        use Symfony\Component\Serializer\Annotation\Groups;
-
-        class MyObj
-        {
-            #[Groups(['group1', 'group2'])]
-            public string $foo;
-
-            #[Groups(['group4'])]
-            public string $anotherProperty;
-
-            #[Groups(['group3'])]
-            public function getBar() // is* methods are also supported
-            {
-                return $this->bar;
-            }
-
-            // ...
-        }
-
-    .. code-block:: yaml
-
-        Acme\MyObj:
-            attributes:
-                foo:
-                    groups: ['group1', 'group2']
-                anotherProperty:
-                    groups: ['group4']
-                bar:
-                    groups: ['group3']
-
-    .. code-block:: xml
-
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
-                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
-        >
-            <class name="Acme\MyObj">
-                <attribute name="foo">
-                    <group>group1</group>
-                    <group>group2</group>
-                </attribute>
-
-                <attribute name="anotherProperty">
-                    <group>group4</group>
-                </attribute>
-
-                <attribute name="bar">
-                    <group>group3</group>
-                </attribute>
-            </class>
-        </serializer>
-
-You are now able to serialize only attributes in the groups you want::
-
-    use Acme\MyObj;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    $obj = new MyObj();
-    $obj->foo = 'foo';
-    $obj->anotherProperty = 'anotherProperty';
-    $obj->setBar('bar');
-
-    $normalizer = new ObjectNormalizer($classMetadataFactory);
-    $serializer = new Serializer([$normalizer]);
-
-    $data = $serializer->normalize($obj, null, ['groups' => 'group1']);
-    // $data = ['foo' => 'foo'];
-
-    $obj2 = $serializer->denormalize(
-        ['foo' => 'foo', 'anotherProperty' => 'anotherProperty', 'bar' => 'bar'],
-        MyObj::class,
-        null,
-        ['groups' => ['group1', 'group3']]
-    );
-    // $obj2 = MyObj(foo: 'foo', bar: 'bar')
-
-    // To get all groups, use the special value `*` in `groups`
-    $obj3 = $serializer->denormalize(
-        ['foo' => 'foo', 'anotherProperty' => 'anotherProperty', 'bar' => 'bar'],
-        MyObj::class,
-        null,
-        ['groups' => ['*']]
-    );
-    // $obj2 = MyObj(foo: 'foo', anotherProperty: 'anotherProperty', bar: 'bar')
-
-.. _ignoring-attributes-when-serializing:
-
-Selecting Specific Attributes
------------------------------
-
-It is also possible to serialize only a set of specific attributes::
-
-    use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    class User
-    {
-        public string $familyName;
-        public string $givenName;
-        public Company $company;
-    }
-
-    class Company
-    {
-        public string $name;
-        public string $address;
-    }
-
-    $company = new Company();
-    $company->name = 'Les-Tilleuls.coop';
-    $company->address = 'Lille, France';
-
-    $user = new User();
-    $user->familyName = 'Dunglas';
-    $user->givenName = 'Kévin';
-    $user->company = $company;
-
-    $serializer = new Serializer([new ObjectNormalizer()]);
-
-    $data = $serializer->normalize($user, null, [AbstractNormalizer::ATTRIBUTES => ['familyName', 'company' => ['name']]]);
-    // $data = ['familyName' => 'Dunglas', 'company' => ['name' => 'Les-Tilleuls.coop']];
-
-Only attributes that are not ignored (see below) are available.
-If some serialization groups are set, only attributes allowed by those groups can be used.
-
-As for groups, attributes can be selected during both the serialization and deserialization processes.
-
-.. _serializer_ignoring-attributes:
-
-Ignoring Attributes
--------------------
-
-All accessible attributes are included by default when serializing objects.
-There are two options to ignore some of those attributes.
-
-Option 1: Using ``#[Ignore]`` Attribute
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. configuration-block::
-
-    .. code-block:: php-attributes
-
-        namespace App\Model;
-
-        use Symfony\Component\Serializer\Annotation\Ignore;
-
-        class MyClass
-        {
-            public string $foo;
-
-            #[Ignore]
-            public string $bar;
-        }
-
-    .. code-block:: yaml
-
-        App\Model\MyClass:
-            attributes:
-                bar:
-                    ignore: true
-
-    .. code-block:: xml
-
-        <?xml version="1.0" ?>
-        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
-                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
-        >
-            <class name="App\Model\MyClass">
-                <attribute name="bar" ignore="true"/>
-            </class>
-        </serializer>
-
-You can now ignore specific attributes during serialization::
-
-    use App\Model\MyClass;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    $obj = new MyClass();
-    $obj->foo = 'foo';
-    $obj->bar = 'bar';
-
-    $normalizer = new ObjectNormalizer($classMetadataFactory);
-    $serializer = new Serializer([$normalizer]);
-
-    $data = $serializer->normalize($obj);
-    // $data = ['foo' => 'foo'];
-
-Option 2: Using the Context
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Pass an array with the names of the attributes to ignore using the
-``AbstractNormalizer::IGNORED_ATTRIBUTES`` key in the ``context`` of the
-serializer method::
-
-    use Acme\Person;
-    use Symfony\Component\Serializer\Encoder\JsonEncoder;
-    use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    $person = new Person();
-    $person->setName('foo');
-    $person->setAge(99);
-
-    $normalizer = new ObjectNormalizer();
-    $encoder = new JsonEncoder();
-
-    $serializer = new Serializer([$normalizer], [$encoder]);
-    $serializer->serialize($person, 'json', [AbstractNormalizer::IGNORED_ATTRIBUTES => ['age']]); // Output: {"name":"foo"}
-
-.. _component-serializer-converting-property-names-when-serializing-and-deserializing:
-
-Converting Property Names when Serializing and Deserializing
-------------------------------------------------------------
-
-Sometimes serialized attributes must be named differently than properties
-or getter/setter methods of PHP classes.
-
-The Serializer component provides a handy way to translate or map PHP field
-names to serialized names: The Name Converter System.
-
-Given you have the following object::
-
-    class Company
-    {
-        public string $name;
-        public string $address;
-    }
-
-And in the serialized form, all attributes must be prefixed by ``org_`` like
-the following::
-
-    {"org_name": "Acme Inc.", "org_address": "123 Main Street, Big City"}
-
-A custom name converter can handle such cases::
-
-    use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
-
-    class OrgPrefixNameConverter implements NameConverterInterface
-    {
-        public function normalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
-        {
-            return 'org_'.$propertyName;
-        }
-
-        public function denormalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
-        {
-            // removes 'org_' prefix
-            return str_starts_with($propertyName, 'org_') ? substr($propertyName, 4) : $propertyName;
-        }
-    }
-
-The custom name converter can be used by passing it as second parameter of any
-class extending :class:`Symfony\\Component\\Serializer\\Normalizer\\AbstractNormalizer`,
-including :class:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer`
-and :class:`Symfony\\Component\\Serializer\\Normalizer\\PropertyNormalizer`::
-
-    use Symfony\Component\Serializer\Encoder\JsonEncoder;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    $nameConverter = new OrgPrefixNameConverter();
-    $normalizer = new ObjectNormalizer(null, $nameConverter);
-
-    $serializer = new Serializer([$normalizer], [new JsonEncoder()]);
-
-    $company = new Company();
-    $company->name = 'Acme Inc.';
-    $company->address = '123 Main Street, Big City';
-
-    $json = $serializer->serialize($company, 'json');
-    // {"org_name": "Acme Inc.", "org_address": "123 Main Street, Big City"}
-    $companyCopy = $serializer->deserialize($json, Company::class, 'json');
-    // Same data as $company
-
-.. _using-camelized-method-names-for-underscored-attributes:
-
-CamelCase to snake_case
-~~~~~~~~~~~~~~~~~~~~~~~
-
-In many formats, it's common to use underscores to separate words (also known
-as snake_case). However, in Symfony applications is common to use CamelCase to
-name properties (even though the `PSR-1 standard`_ doesn't recommend any
-specific case for property names).
-
-Symfony provides a built-in name converter designed to transform between
-snake_case and CamelCased styles during serialization and deserialization
-processes::
-
-    use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-
-    $normalizer = new ObjectNormalizer(null, new CamelCaseToSnakeCaseNameConverter());
-
-    class Person
-    {
-        public function __construct(
-            private string $firstName,
-        ) {
-        }
-
-        public function getFirstName(): string
-        {
-            return $this->firstName;
-        }
-    }
-
-    $kevin = new Person('Kévin');
-    $normalizer->normalize($kevin);
-    // ['first_name' => 'Kévin'];
-
-    $anne = $normalizer->denormalize(['first_name' => 'Anne'], 'Person');
-    // Person object with firstName: 'Anne'
-
-.. _serializer_name-conversion:
-
-Configure name conversion using metadata
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When using this component inside a Symfony application and the class metadata
-factory is enabled as explained in the :ref:`Attributes Groups section <component-serializer-attributes-groups>`,
-this is already set up and you only need to provide the configuration. Otherwise::
-
-    // ...
-    use Symfony\Component\Serializer\Encoder\JsonEncoder;
-    use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
-
-    $metadataAwareNameConverter = new MetadataAwareNameConverter($classMetadataFactory);
-
-    $serializer = new Serializer(
-        [new ObjectNormalizer($classMetadataFactory, $metadataAwareNameConverter)],
-        ['json' => new JsonEncoder()]
-    );
-
-Now configure your name conversion mapping. Consider an application that
-defines a ``Person`` entity with a ``firstName`` property:
-
-.. configuration-block::
-
-    .. code-block:: php-attributes
-
-        namespace App\Entity;
-
-        use Symfony\Component\Serializer\Annotation\SerializedName;
-
-        class Person
-        {
-            public function __construct(
-                #[SerializedName('customer_name')]
-                private string $firstName,
-            ) {
-            }
-
-            // ...
-        }
-
-    .. code-block:: yaml
-
-        App\Entity\Person:
-            attributes:
-                firstName:
-                    serialized_name: customer_name
-
-    .. code-block:: xml
-
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
-                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
-        >
-            <class name="App\Entity\Person">
-                <attribute name="firstName" serialized-name="customer_name"/>
-            </class>
-        </serializer>
-
-This custom mapping is used to convert property names when serializing and
-deserializing objects::
-
-    $serialized = $serializer->serialize(new Person('Kévin'), 'json');
-    // {"customer_name": "Kévin"}
-
-.. _serializing-boolean-attributes:
-
-Handling Boolean Attributes And Values
---------------------------------------
-
-During Serialization
-~~~~~~~~~~~~~~~~~~~~
-
-If you are using isser methods (methods prefixed by ``is``, like
-``App\Model\Person::isSportsperson()``), the Serializer component will
-automatically detect and use it to serialize related attributes.
-
-The ``ObjectNormalizer`` also takes care of methods starting with ``has``, ``get``,
-and ``can``.
-
-During Deserialization
-~~~~~~~~~~~~~~~~~~~~~~
-
-PHP considers many different values as true or false. For example, the
-strings ``true``, ``1``, and ``yes`` are considered true, while
-``false``, ``0``, and ``no`` are considered false.
-
-When deserializing, the Serializer component can take care of this
-automatically. This can be done by using the ``AbstractNormalizer::FILTER_BOOL``
-context option::
-
-    use Acme\Person;
-    use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    $normalizer = new ObjectNormalizer();
-    $serializer = new Serializer([$normalizer]);
-
-    $data = $serializer->denormalize(['sportsperson' => 'yes'], Person::class, context: [AbstractNormalizer::FILTER_BOOL => true]);
-
-This context makes the deserialization process behave like the
-:phpfunction:`filter_var` function with the ``FILTER_VALIDATE_BOOL`` flag.
-
-.. versionadded:: 7.1
-
-    The ``AbstractNormalizer::FILTER_BOOL`` context option was introduced in Symfony 7.1.
-
-Using Callbacks to Serialize Properties with Object Instances
--------------------------------------------------------------
-
-When serializing, you can set a callback to format a specific object property::
-
-    use App\Model\Person;
-    use Symfony\Component\Serializer\Encoder\JsonEncoder;
-    use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    $encoder = new JsonEncoder();
-
-    // all callback parameters are optional (you can omit the ones you don't use)
-    $dateCallback = function (object $attributeValue, object $object, string $attributeName, ?string $format = null, array $context = []): string {
-        return $attributeValue instanceof \DateTime ? $attributeValue->format(\DateTime::ATOM) : '';
-    };
-
-    $defaultContext = [
-        AbstractNormalizer::CALLBACKS => [
-            'createdAt' => $dateCallback,
-        ],
-    ];
-
-    $normalizer = new GetSetMethodNormalizer(null, null, null, null, null, $defaultContext);
-
-    $serializer = new Serializer([$normalizer], [$encoder]);
-
-    $person = new Person();
-    $person->setName('cordoval');
-    $person->setAge(34);
-    $person->setCreatedAt(new \DateTime('now'));
-
-    $serializer->serialize($person, 'json');
-    // Output: {"name":"cordoval", "age": 34, "createdAt": "2014-03-22T09:43:12-0500"}
-
-.. _component-serializer-normalizers:
-
-Normalizers
------------
-
-Normalizers turn **objects** into **arrays** and vice versa. They implement
-:class:`Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface` for
-normalizing (object to array) and
-:class:`Symfony\\Component\\Serializer\\Normalizer\\DenormalizerInterface` for
-denormalizing (array to object).
-
-Normalizers are enabled in the serializer passing them as its first argument::
-
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    $normalizers = [new ObjectNormalizer()];
-    $serializer = new Serializer($normalizers, []);
-
-Built-in Normalizers
-~~~~~~~~~~~~~~~~~~~~
-
-The Serializer component provides several built-in normalizers:
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer`
-    This normalizer leverages the :doc:`PropertyAccess Component </components/property_access>`
-    to read and write in the object. It means that it can access to properties
-    directly and through getters, setters, hassers, issers, canners, adders and removers.
-    It supports calling the constructor during the denormalization process.
-
-    Objects are normalized to a map of property names and values (names are
-    generated by removing the ``get``, ``set``, ``has``, ``is``, ``can``, ``add`` or ``remove``
-    prefix from the method name and transforming the first letter to lowercase; e.g.
-    ``getFirstName()`` -> ``firstName``).
-
-    The ``ObjectNormalizer`` is the most powerful normalizer. It is configured by
-    default in Symfony applications with the Serializer component enabled.
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer`
-    This normalizer reads the content of the class by calling the "getters"
-    (public methods starting with "get"). It will denormalize data by calling
-    the constructor and the "setters" (public methods starting with "set").
-
-    Objects are normalized to a map of property names and values (names are
-    generated by removing the ``get`` prefix from the method name and transforming
-    the first letter to lowercase; e.g. ``getFirstName()`` -> ``firstName``).
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\PropertyNormalizer`
-    This normalizer directly reads and writes public properties as well as
-    **private and protected** properties (from both the class and all of its
-    parent classes) by using `PHP reflection`_. It supports calling the constructor
-    during the denormalization process.
-
-    Objects are normalized to a map of property names to property values.
-
-    If you prefer to only normalize certain properties (e.g. only public properties)
-    set the ``PropertyNormalizer::NORMALIZE_VISIBILITY`` context option and
-    combine the following values: ``PropertyNormalizer::NORMALIZE_PUBLIC``,
-    ``PropertyNormalizer::NORMALIZE_PROTECTED`` or ``PropertyNormalizer::NORMALIZE_PRIVATE``.
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\JsonSerializableNormalizer`
-    This normalizer works with classes that implement :phpclass:`JsonSerializable`.
-
-    It will call the :phpmethod:`JsonSerializable::jsonSerialize` method and
-    then further normalize the result. This means that nested
-    :phpclass:`JsonSerializable` classes will also be normalized.
-
-    This normalizer is particularly helpful when you want to gradually migrate
-    from an existing codebase using simple :phpfunction:`json_encode` to the Symfony
-    Serializer by allowing you to mix which normalizers are used for which classes.
-
-    Unlike with :phpfunction:`json_encode` circular references can be handled.
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeNormalizer`
-    This normalizer converts :phpclass:`DateTimeInterface` objects (e.g.
-    :phpclass:`DateTime` and :phpclass:`DateTimeImmutable`) into strings,
-    integers or floats. By default, it converts them to strings using the `RFC3339`_ format.
-    To convert the objects to integers or floats, set the serializer context option
-    ``DateTimeNormalizer::CAST_KEY`` to ``int`` or ``float``.
-
-    .. versionadded:: 7.1
-
-        The ``DateTimeNormalizer::CAST_KEY`` context option was introduced in Symfony 7.1.
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeZoneNormalizer`
-    This normalizer converts :phpclass:`DateTimeZone` objects into strings that
-    represent the name of the timezone according to the `list of PHP timezones`_.
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\DataUriNormalizer`
-    This normalizer converts :phpclass:`SplFileInfo` objects into a `data URI`_
-    string (``data:...``) such that files can be embedded into serialized data.
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\DateIntervalNormalizer`
-    This normalizer converts :phpclass:`DateInterval` objects into strings.
-    By default, it uses the ``P%yY%mM%dDT%hH%iM%sS`` format.
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\BackedEnumNormalizer`
-    This normalizer converts a \BackedEnum objects into strings or integers.
-
-    By default, an exception is thrown when data is not a valid backed enumeration. If you
-    want ``null`` instead, you can set the ``BackedEnumNormalizer::ALLOW_INVALID_VALUES`` option.
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\FormErrorNormalizer`
-    This normalizer works with classes that implement
-    :class:`Symfony\\Component\\Form\\FormInterface`.
-
-    It will get errors from the form and normalize them into a normalized array.
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\ConstraintViolationListNormalizer`
-    This normalizer converts objects that implement
-    :class:`Symfony\\Component\\Validator\\ConstraintViolationListInterface`
-    into a list of errors according to the `RFC 7807`_ standard.
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\ProblemNormalizer`
-    Normalizes errors according to the API Problem spec `RFC 7807`_.
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\CustomNormalizer`
-    Normalizes a PHP object using an object that implements :class:`Symfony\\Component\\Serializer\\Normalizer\\NormalizableInterface`.
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\UidNormalizer`
-    This normalizer converts objects that extend
-    :class:`Symfony\\Component\\Uid\\AbstractUid` into strings.
-    The default normalization format for objects that implement :class:`Symfony\\Component\\Uid\\Uuid`
-    is the `RFC 4122`_ format (example: ``d9e7a184-5d5b-11ea-a62a-3499710062d0``).
-    The default normalization format for objects that implement :class:`Symfony\\Component\\Uid\\Ulid`
-    is the Base 32 format (example: ``01E439TP9XJZ9RPFH3T1PYBCR8``).
-    You can change the string format by setting the serializer context option
-    ``UidNormalizer::NORMALIZATION_FORMAT_KEY`` to ``UidNormalizer::NORMALIZATION_FORMAT_BASE_58``,
-    ``UidNormalizer::NORMALIZATION_FORMAT_BASE_32`` or ``UidNormalizer::NORMALIZATION_FORMAT_RFC_4122``.
-
-    Also it can denormalize ``uuid`` or ``ulid`` strings to :class:`Symfony\\Component\\Uid\\Uuid`
-    or :class:`Symfony\\Component\\Uid\\Ulid`. The format does not matter.
-
-:class:`Symfony\\Component\\Serializer\\Normalizer\\TranslatableNormalizer`
-    This normalizer converts objects that implement
-    :class:`Symfony\\Contracts\\Translation\\TranslatableInterface` into
-    translated strings, using the
-    :method:`Symfony\\Contracts\\Translation\\TranslatableInterface::trans`
-    method. You can define the locale to use to translate the object by
-    setting the ``TranslatableNormalizer::NORMALIZATION_LOCALE_KEY`` serializer
-    context option.
-
-.. note::
-
-    You can also create your own Normalizer to use another structure. Read more at
-    :doc:`/serializer/custom_normalizer`.
-
-Certain normalizers are enabled by default when using the Serializer component
-in a Symfony application, additional ones can be enabled by tagging them with
-:ref:`serializer.normalizer <reference-dic-tags-serializer-normalizer>`.
-
-Here is an example of how to enable the built-in
-:class:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer`, a
-faster alternative to the
-:class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer`:
-
-.. configuration-block::
-
-    .. code-block:: yaml
-
-        # config/services.yaml
-        services:
-            # ...
-
-            get_set_method_normalizer:
-                class: Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer
-                tags: [serializer.normalizer]
-
-    .. code-block:: xml
-
-        <!-- config/services.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <container xmlns="http://symfony.com/schema/dic/services"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xsi:schemaLocation="http://symfony.com/schema/dic/services
-                https://symfony.com/schema/dic/services/services-1.0.xsd"
-        >
-            <services>
-                <!-- ... -->
-
-                <service id="get_set_method_normalizer" class="Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer">
-                    <tag name="serializer.normalizer"/>
-                </service>
-            </services>
-        </container>
-
-    .. code-block:: php
-
-        // config/services.php
-        namespace Symfony\Component\DependencyInjection\Loader\Configurator;
-
-        use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
-
-        return static function (ContainerConfigurator $container): void {
-            $container->services()
-                // ...
-                ->set('get_set_method_normalizer', GetSetMethodNormalizer::class)
-                    ->tag('serializer.normalizer')
-            ;
-        };
-
-.. _component-serializer-encoders:
-
-Encoders
---------
-
-Encoders turn **arrays** into **formats** and vice versa. They implement
-:class:`Symfony\\Component\\Serializer\\Encoder\\EncoderInterface`
-for encoding (array to format) and
-:class:`Symfony\\Component\\Serializer\\Encoder\\DecoderInterface` for decoding
-(format to array).
-
-You can add new encoders to a Serializer instance by using its second constructor argument::
-
-    use Symfony\Component\Serializer\Encoder\JsonEncoder;
-    use Symfony\Component\Serializer\Encoder\XmlEncoder;
-    use Symfony\Component\Serializer\Serializer;
-
-    $encoders = [new XmlEncoder(), new JsonEncoder()];
-    $serializer = new Serializer([], $encoders);
-
-Built-in Encoders
-~~~~~~~~~~~~~~~~~
-
-The Serializer component provides several built-in encoders:
-
-:class:`Symfony\\Component\\Serializer\\Encoder\\JsonEncoder`
-    This class encodes and decodes data in `JSON`_.
-
-:class:`Symfony\\Component\\Serializer\\Encoder\\XmlEncoder`
-    This class encodes and decodes data in `XML`_.
-
-:class:`Symfony\\Component\\Serializer\\Encoder\\YamlEncoder`
-    This encoder encodes and decodes data in `YAML`_. This encoder requires the
-    :doc:`Yaml Component </components/yaml>`.
-
-:class:`Symfony\\Component\\Serializer\\Encoder\\CsvEncoder`
-    This encoder encodes and decodes data in `CSV`_.
-
-.. note::
-
-    You can also create your own Encoder to use another structure. Read more at
-    :doc:`/serializer/custom_encoders`.
-
-All these encoders are enabled by default when using the Serializer component
-in a Symfony application.
-
-The ``JsonEncoder``
-~~~~~~~~~~~~~~~~~~~
-
-The ``JsonEncoder`` encodes to and decodes from JSON strings, based on the PHP
-:phpfunction:`json_encode` and :phpfunction:`json_decode` functions. It can be
-useful to modify how these functions operate in certain instances by providing
-options such as ``JSON_PRESERVE_ZERO_FRACTION``. You can use the serialization
-context to pass in these options using the key ``json_encode_options`` or
-``json_decode_options`` respectively::
-
-    $this->serializer->serialize($data, 'json', ['json_encode_options' => \JSON_PRESERVE_ZERO_FRACTION]);
-
-These are the options available:
-
-===============================  =========================================================================================================== ================================
-Option                           Description                                                                                                 Default
-===============================  ==========================================================================================================  ================================
-``json_decode_associative``      If set to true returns the result as an array, returns a nested ``stdClass`` hierarchy otherwise.           ``false``
-``json_decode_detailed_errors``  If set to true, exceptions thrown on parsing of JSON are more specific. Requires `seld/jsonlint`_ package.  ``false``
-``json_decode_options``          `$flags`_ passed to :phpfunction:`json_decode` function.                                                    ``0``
-``json_encode_options``          `$flags`_ passed to :phpfunction:`json_encode` function.                                                    ``\JSON_PRESERVE_ZERO_FRACTION``
-``json_decode_recursion_depth``  Sets maximum recursion depth.                                                                               ``512``
-===============================  ==========================================================================================================  ================================
-
-The ``CsvEncoder``
-~~~~~~~~~~~~~~~~~~
-
-The ``CsvEncoder`` encodes to and decodes from CSV.
-
-The ``CsvEncoder`` Context Options
-..................................
-
-The ``encode()`` method defines a third optional parameter called ``context``
-which defines the configuration options for the CsvEncoder an associative array::
-
-    $csvEncoder->encode($array, 'csv', $context);
-
-These are the options available:
-
-======================= ============================================================= ==========================
-Option                  Description                                                   Default
-======================= ============================================================= ==========================
-``csv_delimiter``       Sets the field delimiter separating values (one               ``,``
-                        character only)
-``csv_enclosure``       Sets the field enclosure (one character only)                 ``"``
-``csv_end_of_line``     Sets the character(s) used to mark the end of each            ``\n``
-                        line in the CSV file
-``csv_escape_char``     Deprecated. Sets the escape character (at most one character) empty string
-``csv_key_separator``   Sets the separator for array's keys during its                ``.``
-                        flattening
-``csv_headers``         Sets the order of the header and data columns
-                        E.g.: if ``$data = ['c' => 3, 'a' => 1, 'b' => 2]``
-                        and ``$options = ['csv_headers' => ['a', 'b', 'c']]``
-                        then ``serialize($data, 'csv', $options)`` returns
-                        ``a,b,c\n1,2,3``                                              ``[]``, inferred from input data's keys
-``csv_escape_formulas`` Escapes fields containing formulas by prepending them         ``false``
-                        with a ``\t`` character
-``as_collection``       Always returns results as a collection, even if only          ``true``
-                        one line is decoded.
-``no_headers``          Setting to ``false`` will use first row as headers.           ``false``
-                        ``true`` generate numeric headers.
-``output_utf8_bom``     Outputs special `UTF-8 BOM`_ along with encoded data          ``false``
-======================= ============================================================= ==========================
-
-.. deprecated:: 7.2
-
-    The ``csv_escape_char`` option and the ``CsvEncoder::ESCAPE_CHAR_KEY``
-    constant were deprecated in Symfony 7.2.
-
-The ``XmlEncoder``
-~~~~~~~~~~~~~~~~~~
-
-This encoder transforms arrays into XML and vice versa.
-
-For example, take an object normalized as following::
-
-    ['foo' => [1, 2], 'bar' => true];
-
-The ``XmlEncoder`` will encode this object like that:
-
-.. code-block:: xml
-
-    <?xml version="1.0" encoding="UTF-8" ?>
-    <response>
-        <foo>1</foo>
-        <foo>2</foo>
-        <bar>1</bar>
-    </response>
-
-The special ``#`` key can be used to define the data of a node::
-
-    ['foo' => ['@bar' => 'value', '#' => 'baz']];
-
-    // is encoded as follows:
-    // <?xml version="1.0"?>
-    // <response>
-    //     <foo bar="value">
-    //        baz
-    //     </foo>
-    // </response>
-
-Furthermore, keys beginning with ``@`` will be considered attributes, and
-the key  ``#comment`` can be used for encoding XML comments::
-
-    $encoder = new XmlEncoder();
-    $encoder->encode([
-        'foo' => ['@bar' => 'value'],
-        'qux' => ['#comment' => 'A comment'],
-    ], 'xml');
-    // will return:
-    // <?xml version="1.0"?>
-    // <response>
-    //     <foo bar="value"/>
-    //     <qux><!-- A comment --!><qux>
-    // </response>
-
-You can pass the context key ``as_collection`` in order to have the results
-always as a collection.
-
-.. note::
-
-    You may need to add some attributes on the root node::
-
-        $encoder = new XmlEncoder();
-        $encoder->encode([
-            '@attribute1' => 'foo',
-            '@attribute2' => 'bar',
-            '#' => ['foo' => ['@bar' => 'value', '#' => 'baz']]
-        ], 'xml');
-
-        // will return:
-        // <?xml version="1.0"?>
-        // <response attribute1="foo" attribute2="bar">
-        // <foo bar="value">baz</foo>
-        // </response>
-
-.. tip::
-
-    XML comments are ignored by default when decoding contents, but this
-    behavior can be changed with the optional context key ``XmlEncoder::DECODER_IGNORED_NODE_TYPES``.
-
-    Data with ``#comment`` keys are encoded to XML comments by default. This can be
-    changed by adding the ``\XML_COMMENT_NODE`` option to the ``XmlEncoder::ENCODER_IGNORED_NODE_TYPES``
-    key of the ``$defaultContext`` of the ``XmlEncoder`` constructor or
-    directly to the ``$context`` argument of the ``encode()`` method::
-
-        $xmlEncoder->encode($array, 'xml', [XmlEncoder::ENCODER_IGNORED_NODE_TYPES => [\XML_COMMENT_NODE]]);
-
-The ``XmlEncoder`` Context Options
-..................................
-
-The ``encode()`` method defines a third optional parameter called ``context``
-which defines the configuration options for the XmlEncoder an associative array::
-
-    $xmlEncoder->encode($array, 'xml', $context);
-
-These are the options available:
-
-==============================  =================================================  ==========================
-Option                          Description                                        Default
-==============================  =================================================  ==========================
-``xml_format_output``           If set to true, formats the generated XML with     ``false``
-                                line breaks and indentation
-``xml_version``                 Sets the XML version attribute                     ``1.0``
-``xml_encoding``                Sets the XML encoding attribute                    ``utf-8``
-``xml_standalone``              Adds standalone attribute in the generated XML     ``true``
-``xml_type_cast_attributes``    This provides the ability to forget the attribute  ``true``
-                                type casting
-``xml_root_node_name``          Sets the root node name                            ``response``
-``as_collection``               Always returns results as a collection, even if    ``false``
-                                only one line is decoded
-``decoder_ignored_node_types``  Array of node types (`DOM XML_* constants`_)       ``[\XML_PI_NODE, \XML_COMMENT_NODE]``
-                                to be ignored while decoding
-``encoder_ignored_node_types``  Array of node types (`DOM XML_* constants`_)       ``[]``
-                                to be ignored while encoding
-``load_options``                XML loading `options with libxml`_                 ``\LIBXML_NONET | \LIBXML_NOBLANKS``
-``save_options``                XML saving `options with libxml`_                  ``0``
-``remove_empty_tags``           If set to true, removes all empty tags in the      ``false``
-                                generated XML
-``cdata_wrapping``              If set to false, will not wrap any value           ``true``
-                                matching the ``cdata_wrapping_pattern`` regex in
-                                `a CDATA section`_ like following:
-                                ``<![CDATA[...]]>``
-``cdata_wrapping_pattern``      A regular expression pattern to determine if a     ``/[<>&]/``
-                                value should be wrapped in a CDATA section
-==============================  =================================================  ==========================
-
-.. versionadded:: 7.1
-
-    The ``cdata_wrapping_pattern`` option was introduced in Symfony 7.1.
-
-Example with custom ``context``::
-
-    use Symfony\Component\Serializer\Encoder\XmlEncoder;
-
-    // create encoder with specified options as new default settings
-    $xmlEncoder = new XmlEncoder(['xml_format_output' => true]);
-
-    $data = [
-        'id' => 'IDHNQIItNyQ',
-        'date' => '2019-10-24',
-    ];
-
-    // encode with default context
-    $xmlEncoder->encode($data, 'xml');
-    // outputs:
-    // <?xml version="1.0"?>
-    // <response>
-    //   <id>IDHNQIItNyQ</id>
-    //   <date>2019-10-24</date>
-    // </response>
-
-    // encode with modified context
-    $xmlEncoder->encode($data, 'xml', [
-        'xml_root_node_name' => 'track',
-        'encoder_ignored_node_types' => [
-            \XML_PI_NODE, // removes XML declaration (the leading xml tag)
-        ],
-    ]);
-    // outputs:
-    // <track>
-    //   <id>IDHNQIItNyQ</id>
-    //   <date>2019-10-24</date>
-    // </track>
-
-The ``YamlEncoder``
-~~~~~~~~~~~~~~~~~~~
-
-This encoder requires the :doc:`Yaml Component </components/yaml>` and
-transforms from and to Yaml.
-
-The ``YamlEncoder`` Context Options
-...................................
-
-The ``encode()`` method, like other encoder, uses ``context`` to set
-configuration options for the YamlEncoder an associative array::
-
-    $yamlEncoder->encode($array, 'yaml', $context);
-
-These are the options available:
-
-=============== ========================================================  ==========================
-Option          Description                                               Default
-=============== ========================================================  ==========================
-``yaml_inline`` The level where you switch to inline YAML                 ``0``
-``yaml_indent`` The level of indentation (used internally)                ``0``
-``yaml_flags``  A bit field of ``Yaml::DUMP_*`` / ``PARSE_*`` constants   ``0``
-                to customize the encoding / decoding YAML string
-=============== ========================================================  ==========================
-
-.. _component-serializer-context-builders:
-
-Context Builders
-----------------
-
-Instead of passing plain PHP arrays to the :ref:`serialization context <serializer_serializer-context>`,
-you can use "context builders" to define the context using a fluent interface::
-
-    use Symfony\Component\Serializer\Context\Encoder\CsvEncoderContextBuilder;
-    use Symfony\Component\Serializer\Context\Normalizer\ObjectNormalizerContextBuilder;
-
-    $initialContext = [
-        'custom_key' => 'custom_value',
-    ];
-
-    $contextBuilder = (new ObjectNormalizerContextBuilder())
-        ->withContext($initialContext)
-        ->withGroups(['group1', 'group2']);
-
-    $contextBuilder = (new CsvEncoderContextBuilder())
-        ->withContext($contextBuilder)
-        ->withDelimiter(';');
-
-    $serializer->serialize($something, 'csv', $contextBuilder->toArray());
-
-.. note::
-
-    The Serializer component provides a context builder
-    for each :ref:`normalizer <component-serializer-normalizers>`
-    and :ref:`encoder <component-serializer-encoders>`.
-
-    You can also :doc:`create custom context builders </serializer/custom_context_builders>`
-    to deal with your context values.
-
-.. deprecated:: 7.2
-
-    The ``CsvEncoderContextBuilder::withEscapeChar()`` method was deprecated
-    in Symfony 7.2.
-
-Skipping ``null`` Values
-------------------------
-
-By default, the Serializer will preserve properties containing a ``null`` value.
-You can change this behavior by setting the ``AbstractObjectNormalizer::SKIP_NULL_VALUES`` context option
-to ``true``::
-
-    $dummy = new class {
-        public ?string $foo = null;
-        public string $bar = 'notNull';
-    };
-
-    $normalizer = new ObjectNormalizer();
-    $result = $normalizer->normalize($dummy, 'json', [AbstractObjectNormalizer::SKIP_NULL_VALUES => true]);
-    // ['bar' => 'notNull']
-
-Require all Properties
-----------------------
-
-By default, the Serializer will add ``null`` to nullable properties when the parameters for those are not provided.
-You can change this behavior by setting the ``AbstractNormalizer::REQUIRE_ALL_PROPERTIES`` context option
-to ``true``::
-
-    class Dummy
-    {
-        public function __construct(
-            public string $foo,
-            public ?string $bar,
-        ) {
-        }
-    }
-
-    $data = ['foo' => 'notNull'];
-
-    $normalizer = new ObjectNormalizer();
-    $result = $normalizer->denormalize($data, Dummy::class, 'json', [AbstractNormalizer::REQUIRE_ALL_PROPERTIES => true]);
-    // throws Symfony\Component\Serializer\Exception\MissingConstructorArgumentException
-
-Skipping Uninitialized Properties
----------------------------------
-
-In PHP, typed properties have an ``uninitialized`` state which is different
-from the default ``null`` of untyped properties. When you try to access a typed
-property before giving it an explicit value, you get an error.
-
-To avoid the Serializer throwing an error when serializing or normalizing an
-object with uninitialized properties, by default the object normalizer catches
-these errors and ignores such properties.
-
-You can disable this behavior by setting the ``AbstractObjectNormalizer::SKIP_UNINITIALIZED_VALUES``
-context option to ``false``::
-
-    class Dummy {
-        public string $foo = 'initialized';
-        public string $bar; // uninitialized
-    }
-
-    $normalizer = new ObjectNormalizer();
-    $result = $normalizer->normalize(new Dummy(), 'json', [AbstractObjectNormalizer::SKIP_UNINITIALIZED_VALUES => false]);
-    // throws Symfony\Component\PropertyAccess\Exception\UninitializedPropertyException as normalizer cannot read uninitialized properties
-
-.. note::
-
-    Calling ``PropertyNormalizer::normalize`` or ``GetSetMethodNormalizer::normalize``
-    with ``AbstractObjectNormalizer::SKIP_UNINITIALIZED_VALUES`` context option set
-    to ``false`` will throw an ``\Error`` instance if the given object has uninitialized
-    properties as the normalizer cannot read them (directly or via getter/isser methods).
-
-.. _component-serializer-handling-circular-references:
-
-Collecting Type Errors While Denormalizing
-------------------------------------------
-
-When denormalizing a payload to an object with typed properties, you'll get an
-exception if the payload contains properties that don't have the same type as
-the object.
-
-In those situations, use the ``COLLECT_DENORMALIZATION_ERRORS`` option to
-collect all exceptions at once, and to get the object partially denormalized::
-
-    try {
-        $dto = $serializer->deserialize($request->getContent(), MyDto::class, 'json', [
-            DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true,
-        ]);
-    } catch (PartialDenormalizationException $e) {
-        $violations = new ConstraintViolationList();
-        /** @var NotNormalizableValueException $exception */
-        foreach ($e->getErrors() as $exception) {
-            $message = sprintf('The type must be one of "%s" ("%s" given).', implode(', ', $exception->getExpectedTypes()), $exception->getCurrentType());
-            $parameters = [];
-            if ($exception->canUseMessageForUser()) {
-                $parameters['hint'] = $exception->getMessage();
-            }
-            $violations->add(new ConstraintViolation($message, '', $parameters, null, $exception->getPath(), null));
-        }
-
-        return $this->json($violations, 400);
-    }
-
-Handling Circular References
-----------------------------
-
-Circular references are common when dealing with entity relations::
-
-    class Organization
-    {
-        private string $name;
-        private array $members;
-
-        public function setName($name): void
-        {
-            $this->name = $name;
-        }
-
-        public function getName(): string
-        {
-            return $this->name;
-        }
-
-        public function setMembers(array $members): void
-        {
-            $this->members = $members;
-        }
-
-        public function getMembers(): array
-        {
-            return $this->members;
-        }
-    }
-
-    class Member
-    {
-        private string $name;
-        private Organization $organization;
-
-        public function setName(string $name): void
-        {
-            $this->name = $name;
-        }
-
-        public function getName(): string
-        {
-            return $this->name;
-        }
-
-        public function setOrganization(Organization $organization): void
-        {
-            $this->organization = $organization;
-        }
-
-        public function getOrganization(): Organization
-        {
-            return $this->organization;
-        }
-    }
-
-To avoid infinite loops, :class:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer`
-or :class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer`
-throw a :class:`Symfony\\Component\\Serializer\\Exception\\CircularReferenceException`
-when such a case is encountered::
-
-    $member = new Member();
-    $member->setName('Kévin');
-
-    $organization = new Organization();
-    $organization->setName('Les-Tilleuls.coop');
-    $organization->setMembers([$member]);
-
-    $member->setOrganization($organization);
-
-    echo $serializer->serialize($organization, 'json'); // Throws a CircularReferenceException
-
-The key ``circular_reference_limit`` in the default context sets the number of
-times it will serialize the same object before considering it a circular
-reference. The default value is ``1``.
-
-Instead of throwing an exception, circular references can also be handled
-by custom callables. This is especially useful when serializing entities
-having unique identifiers::
-
-    $encoder = new JsonEncoder();
-    $defaultContext = [
-        AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function (object $object, ?string $format, array $context): string {
-            return $object->getName();
-        },
-    ];
-    $normalizer = new ObjectNormalizer(null, null, null, null, null, null, $defaultContext);
-
-    $serializer = new Serializer([$normalizer], [$encoder]);
-    var_dump($serializer->serialize($org, 'json'));
-    // {"name":"Les-Tilleuls.coop","members":[{"name":"K\u00e9vin", organization: "Les-Tilleuls.coop"}]}
-
-.. _serializer_handling-serialization-depth:
-
-Handling Serialization Depth
-----------------------------
-
-The Serializer component is able to detect and limit the serialization depth.
-It is especially useful when serializing large trees. Assume the following data
-structure::
-
-    namespace Acme;
-
-    class MyObj
-    {
-        public string $foo;
-
-        /**
-         * @var self
-         */
-        public MyObj $child;
-    }
-
-    $level1 = new MyObj();
-    $level1->foo = 'level1';
-
-    $level2 = new MyObj();
-    $level2->foo = 'level2';
-    $level1->child = $level2;
-
-    $level3 = new MyObj();
-    $level3->foo = 'level3';
-    $level2->child = $level3;
-
-The serializer can be configured to set a maximum depth for a given property.
-Here, we set it to 2 for the ``$child`` property:
-
-.. configuration-block::
-
-    .. code-block:: php-attributes
-
-        namespace Acme;
-
-        use Symfony\Component\Serializer\Annotation\MaxDepth;
-
-        class MyObj
-        {
-            #[MaxDepth(2)]
-            public MyObj $child;
-
-            // ...
-        }
-
-    .. code-block:: yaml
-
-        Acme\MyObj:
-            attributes:
-                child:
-                    max_depth: 2
-
-    .. code-block:: xml
-
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
-                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
-        >
-            <class name="Acme\MyObj">
-                <attribute name="child" max-depth="2"/>
-            </class>
-        </serializer>
-
-The metadata loader corresponding to the chosen format must be configured in
-order to use this feature. It is done automatically when using the Serializer component
-in a Symfony application. When using the standalone component, refer to
-:ref:`the groups documentation <component-serializer-attributes-groups>` to
-learn how to do that.
-
-The check is only done if the ``AbstractObjectNormalizer::ENABLE_MAX_DEPTH`` key of the serializer context
-is set to ``true``. In the following example, the third level is not serialized
-because it is deeper than the configured maximum depth of 2::
-
-    $result = $serializer->normalize($level1, null, [AbstractObjectNormalizer::ENABLE_MAX_DEPTH => true]);
-    /*
-    $result = [
-        'foo' => 'level1',
-        'child' => [
-            'foo' => 'level2',
-            'child' => [
-                'child' => null,
-            ],
-        ],
-    ];
-    */
-
-Instead of throwing an exception, a custom callable can be executed when the
-maximum depth is reached. This is especially useful when serializing entities
-having unique identifiers::
-
-    use Symfony\Component\Serializer\Annotation\MaxDepth;
-    use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
-    use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader;
-    use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    class Foo
-    {
-        public int $id;
-
-        #[MaxDepth(1)]
-        public MyObj $child;
-    }
-
-    $level1 = new Foo();
-    $level1->id = 1;
-
-    $level2 = new Foo();
-    $level2->id = 2;
-    $level1->child = $level2;
-
-    $level3 = new Foo();
-    $level3->id = 3;
-    $level2->child = $level3;
-
-    $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
-
-    // all callback parameters are optional (you can omit the ones you don't use)
-    $maxDepthHandler = function (object $innerObject, object $outerObject, string $attributeName, ?string $format = null, array $context = []): string {
-        return '/foos/'.$innerObject->id;
-    };
-
-    $defaultContext = [
-        AbstractObjectNormalizer::MAX_DEPTH_HANDLER => $maxDepthHandler,
-    ];
-    $normalizer = new ObjectNormalizer($classMetadataFactory, null, null, null, null, null, $defaultContext);
-
-    $serializer = new Serializer([$normalizer]);
-
-    $result = $serializer->normalize($level1, null, [AbstractObjectNormalizer::ENABLE_MAX_DEPTH => true]);
-    /*
-    $result = [
-        'id' => 1,
-        'child' => [
-            'id' => 2,
-            'child' => '/foos/3',
-        ],
-    ];
-    */
-
-Handling Arrays
----------------
-
-The Serializer component is capable of handling arrays of objects as well.
-Serializing arrays works just like serializing a single object::
-
-    use Acme\Person;
-
-    $person1 = new Person();
-    $person1->setName('foo');
-    $person1->setAge(99);
-    $person1->setSportsman(false);
-
-    $person2 = new Person();
-    $person2->setName('bar');
-    $person2->setAge(33);
-    $person2->setSportsman(true);
-
-    $persons = [$person1, $person2];
-    $data = $serializer->serialize($persons, 'json');
-
-    // $data contains [{"name":"foo","age":99,"sportsman":false},{"name":"bar","age":33,"sportsman":true}]
-
-If you want to deserialize such a structure, you need to add the
-:class:`Symfony\\Component\\Serializer\\Normalizer\\ArrayDenormalizer`
-to the set of normalizers. By appending ``[]`` to the type parameter of the
-:method:`Symfony\\Component\\Serializer\\Serializer::deserialize` method,
-you indicate that you're expecting an array instead of a single object::
-
-    use Symfony\Component\Serializer\Encoder\JsonEncoder;
-    use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
-    use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    $serializer = new Serializer(
-        [new GetSetMethodNormalizer(), new ArrayDenormalizer()],
-        [new JsonEncoder()]
-    );
-
-    $data = ...; // The serialized data from the previous example
-    $persons = $serializer->deserialize($data, 'Acme\Person[]', 'json');
-
-Handling Constructor Arguments
-------------------------------
-
-If the class constructor defines arguments, as usually happens with
-`Value Objects`_, the serializer won't be able to create the object if some
-arguments are missing. In those cases, use the ``default_constructor_arguments``
-context option::
-
-    use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    class MyObj
-    {
-        public function __construct(
-            private string $foo,
-            private string $bar,
-        ) {
-        }
-    }
-
-    $normalizer = new ObjectNormalizer();
-    $serializer = new Serializer([$normalizer]);
-
-    $data = $serializer->denormalize(
-        ['foo' => 'Hello'],
-        'MyObj',
-        null,
-        [AbstractNormalizer::DEFAULT_CONSTRUCTOR_ARGUMENTS => [
-            'MyObj' => ['foo' => '', 'bar' => ''],
-        ]]
-    );
-    // $data = new MyObj('Hello', '');
-
-Recursive Denormalization and Type Safety
------------------------------------------
-
-The Serializer component can use the :doc:`PropertyInfo Component </components/property_info>` to denormalize
-complex types (objects). The type of the class' property will be guessed using the provided
-extractor and used to recursively denormalize the inner data.
-
-When using this component in a Symfony application, all normalizers are automatically configured to use the registered extractors.
-When using the component standalone, an implementation of :class:`Symfony\\Component\\PropertyInfo\\PropertyTypeExtractorInterface`,
-(usually an instance of :class:`Symfony\\Component\\PropertyInfo\\PropertyInfoExtractor`) must be passed as the 4th
-parameter of the ``ObjectNormalizer``::
-
-    namespace Acme;
-
-    use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
-    use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    class ObjectOuter
-    {
-        private ObjectInner $inner;
-        private \DateTimeInterface $date;
-
-        public function getInner(): ObjectInner
-        {
-            return $this->inner;
-        }
-
-        public function setInner(ObjectInner $inner): void
-        {
-            $this->inner = $inner;
-        }
-
-        public function getDate(): \DateTimeInterface
-        {
-            return $this->date;
-        }
-
-        public function setDate(\DateTimeInterface $date): void
-        {
-            $this->date = $date;
-        }
-    }
-
-    class ObjectInner
-    {
-        public string $foo;
-        public string $bar;
-    }
-
-    $normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
-    $serializer = new Serializer([new DateTimeNormalizer(), $normalizer]);
-
-    $obj = $serializer->denormalize(
-        ['inner' => ['foo' => 'foo', 'bar' => 'bar'], 'date' => '1988/01/21'],
-        'Acme\ObjectOuter'
-    );
-
-    dump($obj->getInner()->foo); // 'foo'
-    dump($obj->getInner()->bar); // 'bar'
-    dump($obj->getDate()->format('Y-m-d')); // '1988-01-21'
-
-When a ``PropertyTypeExtractor`` is available, the normalizer will also check that the data to denormalize
-matches the type of the property (even for primitive types). For instance, if a ``string`` is provided, but
-the type of the property is ``int``, an :class:`Symfony\\Component\\Serializer\\Exception\\UnexpectedValueException`
-will be thrown. The type enforcement of the properties can be disabled by setting
-the serializer context option ``ObjectNormalizer::DISABLE_TYPE_ENFORCEMENT``
-to ``true``.
-
-.. _serializer_interfaces-and-abstract-classes:
-
-Serializing Interfaces and Abstract Classes
--------------------------------------------
-
-When dealing with objects that are fairly similar or share properties, you may
-use interfaces or abstract classes. The Serializer component allows you to
-serialize and deserialize these objects using a *"discriminator class mapping"*.
-
-The discriminator is the field (in the serialized string) used to differentiate
-between the possible objects. In practice, when using the Serializer component,
-pass a :class:`Symfony\\Component\\Serializer\\Mapping\\ClassDiscriminatorResolverInterface`
-implementation to the :class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer`.
-
-The Serializer component provides an implementation of ``ClassDiscriminatorResolverInterface``
-called :class:`Symfony\\Component\\Serializer\\Mapping\\ClassDiscriminatorFromClassMetadata`
-which uses the class metadata factory and a mapping configuration to serialize
-and deserialize objects of the correct class.
-
-When using this component inside a Symfony application and the class metadata factory is enabled
-as explained in the :ref:`Attributes Groups section <component-serializer-attributes-groups>`,
-this is already set up and you only need to provide the configuration. Otherwise::
-
-    // ...
-    use Symfony\Component\Serializer\Encoder\JsonEncoder;
-    use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata;
-    use Symfony\Component\Serializer\Mapping\ClassDiscriminatorMapping;
-    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-    use Symfony\Component\Serializer\Serializer;
-
-    $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
-
-    $discriminator = new ClassDiscriminatorFromClassMetadata($classMetadataFactory);
-
-    $serializer = new Serializer(
-        [new ObjectNormalizer($classMetadataFactory, null, null, null, $discriminator)],
-        ['json' => new JsonEncoder()]
-    );
-
-Now configure your discriminator class mapping. Consider an application that
-defines an abstract ``CodeRepository`` class extended by ``GitHubCodeRepository``
-and ``BitBucketCodeRepository`` classes:
-
-.. configuration-block::
-
-    .. code-block:: php-attributes
-
-        namespace App;
-
-        use App\BitBucketCodeRepository;
-        use App\GitHubCodeRepository;
-        use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
-
-        #[DiscriminatorMap(typeProperty: 'type', mapping: [
-            'github' => GitHubCodeRepository::class,
-            'bitbucket' => BitBucketCodeRepository::class,
-        ])]
-        abstract class CodeRepository
-        {
-            // ...
-        }
-
-    .. code-block:: yaml
-
-        App\CodeRepository:
-            discriminator_map:
-                type_property: type
-                mapping:
-                    github: 'App\GitHubCodeRepository'
-                    bitbucket: 'App\BitBucketCodeRepository'
-
-    .. code-block:: xml
-
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
-                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
-        >
-            <class name="App\CodeRepository">
-                <discriminator-map type-property="type">
-                    <mapping type="github" class="App\GitHubCodeRepository"/>
-                    <mapping type="bitbucket" class="App\BitBucketCodeRepository"/>
-                </discriminator-map>
-            </class>
-        </serializer>
-
-.. note::
-
-    The values of the ``mapping`` array option must be strings.
-    Otherwise, they will be cast into strings automatically.
-
-Once configured, the serializer uses the mapping to pick the correct class::
-
-    $serialized = $serializer->serialize(new GitHubCodeRepository(), 'json');
-    // {"type": "github"}
-
-    $repository = $serializer->deserialize($serialized, CodeRepository::class, 'json');
-    // instanceof GitHubCodeRepository
-
-Learn more
-----------
-
-.. toctree::
-    :maxdepth: 1
-    :glob:
-
-    /serializer
-
-.. seealso::
-
-    Normalizers for the Symfony Serializer Component supporting popular web API formats
-    (JSON-LD, GraphQL, OpenAPI, HAL, JSON:API) are available as part of the `API Platform`_ project.
-
-.. seealso::
-
-    A popular alternative to the Symfony Serializer component is the third-party
-    library, `JMS serializer`_ (versions before ``v1.12.0`` were released under
-    the Apache license, so incompatible with GPLv2 projects).
-
-.. _`PSR-1 standard`: https://www.php-fig.org/psr/psr-1/
-.. _`JMS serializer`: https://github.com/schmittjoh/serializer
-.. _RFC3339: https://tools.ietf.org/html/rfc3339#section-5.8
-.. _`options with libxml`: https://www.php.net/manual/en/libxml.constants.php
-.. _`DOM XML_* constants`: https://www.php.net/manual/en/dom.constants.php
-.. _JSON: https://www.json.org/json-en.html
-.. _XML: https://www.w3.org/XML/
-.. _YAML: https://yaml.org/
-.. _CSV: https://tools.ietf.org/html/rfc4180
-.. _`RFC 7807`: https://tools.ietf.org/html/rfc7807
-.. _`UTF-8 BOM`: https://en.wikipedia.org/wiki/Byte_order_mark
-.. _`Value Objects`: https://en.wikipedia.org/wiki/Value_object
-.. _`API Platform`: https://api-platform.com
-.. _`list of PHP timezones`: https://www.php.net/manual/en/timezones.php
-.. _`RFC 4122`: https://tools.ietf.org/html/rfc4122
-.. _`PHP reflection`: https://php.net/manual/en/book.reflection.php
-.. _`data URI`: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
-.. _seld/jsonlint: https://github.com/Seldaek/jsonlint
-.. _$flags: https://www.php.net/manual/en/json.constants.php
-.. _`a CDATA section`: https://en.wikipedia.org/wiki/CDATA
diff --git a/components/type_info.rst b/components/type_info.rst
index 30ae11aa222..47fe9dfd9ba 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -11,11 +11,6 @@ This component provides:
 * A way to get types from PHP elements such as properties, method arguments,
   return types, and raw strings.
 
-.. caution::
-
-    This component is :doc:`experimental </contributing/code/experimental>` and
-    could be changed at any time without prior notice.
-
 Installation
 ------------
 
@@ -45,12 +40,24 @@ to the :class:`Symfony\\Component\\TypeInfo\\Type` static methods as following::
     // Many others are available and can be
     // found in Symfony\Component\TypeInfo\TypeFactoryTrait
 
-The second way of using the component is to use ``TypeInfo`` to resolve a type
-based on reflection or a simple string::
+Resolvers
+~~~~~~~~~
+
+The second way to use the component is by using ``TypeInfo`` to resolve a type
+based on reflection or a simple string. This approach is designed for libraries
+that need a simple way to describe a class or anything with a type::
 
     use Symfony\Component\TypeInfo\Type;
     use Symfony\Component\TypeInfo\TypeResolver\TypeResolver;
 
+    class Dummy
+    {
+        public function __construct(
+            public int $id,
+        ) {
+        }
+    }
+
     // Instantiate a new resolver
     $typeResolver = TypeResolver::create();
 
@@ -63,12 +70,6 @@ based on reflection or a simple string::
 
     // Type instances have several helper methods
 
-    // returns the main type (e.g. in this example it returns an "array" Type instance);
-    // for nullable types (e.g. string|null) it returns the non-null type (e.g. string)
-    // and for compound types (e.g. int|string) it throws an exception because both types
-    // can be considered the main one, so there's no way to pick one
-    $baseType = $type->getBaseType();
-
     // for collections, it returns the type of the item used as the key;
     // in this example, the collection is a list, so it returns an "int" Type instance
     $keyType = $type->getCollectionKeyType();
@@ -81,6 +82,111 @@ Each of these calls will return you a ``Type`` instance that corresponds to the
 static method used. You can also resolve types from a string (as shown in the
 ``bool`` parameter of the previous example)
 
-.. note::
+PHPDoc Parsing
+~~~~~~~~~~~~~~
+
+In many cases, you may not have cleanly typed properties or may need more precise
+type definitions provided by advanced PHPDoc. To achieve this, you can use a string
+resolver based on the PHPDoc annotations.
+
+First, run the command ``composer require phpstan/phpdoc-parser`` to install the
+PHP package required for string resolving. Then, follow these steps::
+
+    use Symfony\Component\TypeInfo\TypeResolver\TypeResolver;
+
+    class Dummy
+    {
+        public function __construct(
+            public int $id,
+            /** @var string[] $tags */
+            public array $tags,
+        ) {
+        }
+    }
+
+    $typeResolver = TypeResolver::create();
+    $typeResolver->resolve(new \ReflectionProperty(Dummy::class, 'id')); // returns an "int" Type
+    $typeResolver->resolve(new \ReflectionProperty(Dummy::class, 'id')); // returns a collection with "int" as key and "string" as values Type
+
+Advanced Usages
+~~~~~~~~~~~~~~~
+
+The TypeInfo component provides various methods to manipulate and check types,
+depending on your needs.
+
+**Identify** a type::
+
+    // define a simple integer type
+    $type = Type::int();
+    // check if the type matches a specific identifier
+    $type->isIdentifiedBy(TypeIdentifier::INT);    // true
+    $type->isIdentifiedBy(TypeIdentifier::STRING); // false
+
+    // define a union type (equivalent to PHP's int|string)
+    $type = Type::union(Type::string(), Type::int());
+    // now the second check is true because the union type contains the string type
+    $type->isIdentifiedBy(TypeIdentifier::INT);    // true
+    $type->isIdentifiedBy(TypeIdentifier::STRING); // true
+
+    class DummyParent {}
+    class Dummy extends DummyParent implements DummyInterface {}
+
+    // define an object type
+    $type = Type::object(Dummy::class);
+
+    // check if the type is an object or matches a specific class
+    $type->isIdentifiedBy(TypeIdentifier::OBJECT); // true
+    $type->isIdentifiedBy(Dummy::class);           // true
+    // check if it inherits/implements something
+    $type->isIdentifiedBy(DummyParent::class);     // true
+    $type->isIdentifiedBy(DummyInterface::class);  // true
+
+Checking if a type **accepts a value**::
+
+    $type = Type::int();
+    // check if the type accepts a given value
+    $type->accepts(123); // true
+    $type->accepts('z'); // false
+
+    $type = Type::union(Type::string(), Type::int());
+    // now the second check is true because the union type accepts either an int or a string value
+    $type->accepts(123); // true
+    $type->accepts('z'); // true
+
+.. versionadded:: 7.3
+
+    The :method:`Symfony\\Component\\TypeInfo\\Type::accepts`
+    method was introduced in Symfony 7.3.
+
+Using callables for **complex checks**::
+
+    class Foo
+    {
+        private int $integer;
+        private string $string;
+        private ?float $float;
+    }
+
+    $reflClass = new \ReflectionClass(Foo::class);
+
+    $resolver = TypeResolver::create();
+    $integerType = $resolver->resolve($reflClass->getProperty('integer'));
+    $stringType = $resolver->resolve($reflClass->getProperty('string'));
+    $floatType = $resolver->resolve($reflClass->getProperty('float'));
+
+    // define a callable to validate non-nullable number types
+    $isNonNullableNumber = function (Type $type): bool {
+        if ($type->isNullable()) {
+            return false;
+        }
+
+        if ($type->isIdentifiedBy(TypeIdentifier::INT) || $type->isIdentifiedBy(TypeIdentifier::FLOAT)) {
+            return true;
+        }
+
+        return false;
+    };
 
-    To support raw string resolving, you need to install ``phpstan/phpdoc-parser`` package.
+    $integerType->isSatisfiedBy($isNonNullableNumber); // true
+    $stringType->isSatisfiedBy($isNonNullableNumber);  // false
+    $floatType->isSatisfiedBy($isNonNullableNumber);   // false
diff --git a/components/uid.rst b/components/uid.rst
index 73974ef8732..6c92fff0af9 100644
--- a/components/uid.rst
+++ b/components/uid.rst
@@ -386,7 +386,7 @@ entity primary keys::
         // ...
     }
 
-.. caution::
+.. warning::
 
     Using UUIDs as primary keys is usually not recommended for performance reasons:
     indexes are slower and take more space (because UUIDs in binary format take
@@ -574,7 +574,7 @@ entity primary keys::
         // ...
     }
 
-.. caution::
+.. warning::
 
     Using ULIDs as primary keys is usually not recommended for performance reasons.
     Although ULIDs don't suffer from index fragmentation issues (because the values
diff --git a/components/validator/resources.rst b/components/validator/resources.rst
index c1474c1710d..5b1448dfba1 100644
--- a/components/validator/resources.rst
+++ b/components/validator/resources.rst
@@ -171,7 +171,7 @@ You can set this custom implementation using
         ->setMetadataFactory(new CustomMetadataFactory(...))
         ->getValidator();
 
-.. caution::
+.. warning::
 
     Since you are using a custom metadata factory, you can't configure loaders
     and caches using the ``add*Mapping()`` methods anymore. You now have to
diff --git a/components/yaml.rst b/components/yaml.rst
index 30f715a7a24..58436adffc2 100644
--- a/components/yaml.rst
+++ b/components/yaml.rst
@@ -428,6 +428,16 @@ you can dump them as ``~`` with the ``DUMP_NULL_AS_TILDE`` flag::
     $dumped = Yaml::dump(['foo' => null], 2, 4, Yaml::DUMP_NULL_AS_TILDE);
     // foo: ~
 
+Another valid representation of the ``null`` value is an empty string. You can
+use the ``DUMP_NULL_AS_EMPTY`` flag to dump null values as empty strings::
+
+    $dumped = Yaml::dump(['foo' => null], 2, 4, Yaml::DUMP_NULL_AS_EMPTY);
+    // foo:
+
+.. versionadded:: 7.3
+
+    The ``DUMP_NULL_AS_EMPTY`` flag was introduced in Symfony 7.3.
+
 Dumping Numeric Keys as Strings
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/configuration.rst b/configuration.rst
index 51ad9368098..35bc2fb7eec 100644
--- a/configuration.rst
+++ b/configuration.rst
@@ -267,7 +267,7 @@ reusable configuration value. By convention, parameters are defined under the
 
         // ...
 
-.. caution::
+.. warning::
 
     By default and when using XML configuration, the values between ``<parameter>``
     tags are not trimmed. This means that the value of the following parameter will be
@@ -379,7 +379,7 @@ a new ``locale`` parameter is added to the ``config/services.yaml`` file).
 
     By convention, parameters whose names start with a dot ``.`` (for example,
     ``.mailer.transport``), are available only during the container compilation.
-    They are useful when working with :ref:`Compiler Passes </service_container/compiler_passes>`
+    They are useful when working with :doc:`Compiler Passes </service_container/compiler_passes>`
     to declare some temporary parameters that won't be available later in the application.
 
 Configuration parameters are usually validation-free, but you can ensure that
@@ -809,7 +809,7 @@ Use environment variables in values by prefixing variables with ``$``:
     DB_USER=root
     DB_PASS=${DB_USER}pass # include the user as a password prefix
 
-.. caution::
+.. warning::
 
     The order is important when some env var depends on the value of other env
     vars. In the above example, ``DB_PASS`` must be defined after ``DB_USER``.
@@ -830,7 +830,7 @@ Embed commands via ``$()`` (not supported on Windows):
 
     START_TIME=$(date)
 
-.. caution::
+.. warning::
 
     Using ``$()`` might not work depending on your shell.
 
diff --git a/configuration/env_var_processors.rst b/configuration/env_var_processors.rst
index baf4037d05a..2e82104db66 100644
--- a/configuration/env_var_processors.rst
+++ b/configuration/env_var_processors.rst
@@ -687,7 +687,7 @@ Symfony provides the following env var processors:
                 ],
             ]);
 
-    .. caution::
+    .. warning::
 
         In order to ease extraction of the resource from the URL, the leading
         ``/`` is trimmed from the ``path`` component.
diff --git a/configuration/micro_kernel_trait.rst b/configuration/micro_kernel_trait.rst
index c9739679f69..62e8c2d4128 100644
--- a/configuration/micro_kernel_trait.rst
+++ b/configuration/micro_kernel_trait.rst
@@ -16,7 +16,7 @@ via Composer:
 
 .. code-block:: terminal
 
-    $ composer symfony/framework-bundle symfony/runtime
+    $ composer require symfony/framework-bundle symfony/runtime
 
 Next, create an ``index.php`` file that defines the kernel class and runs it:
 
diff --git a/configuration/multiple_kernels.rst b/configuration/multiple_kernels.rst
index 512ea57f24d..ec8742213b5 100644
--- a/configuration/multiple_kernels.rst
+++ b/configuration/multiple_kernels.rst
@@ -229,7 +229,7 @@ but it should typically be added to your web server configuration.
     # .env
     APP_ID=api
 
-.. caution::
+.. warning::
 
     The value of this variable must match the application directory within
     ``apps/`` as it is used in the Kernel to load the specific application
diff --git a/configuration/override_dir_structure.rst b/configuration/override_dir_structure.rst
index d17b67aedba..e5dff35b6d0 100644
--- a/configuration/override_dir_structure.rst
+++ b/configuration/override_dir_structure.rst
@@ -111,7 +111,7 @@ In this case you have changed the location of the cache directory to
 You can also change the cache directory by defining an environment variable
 named ``APP_CACHE_DIR`` whose value is the full path of the cache folder.
 
-.. caution::
+.. warning::
 
     You should keep the cache directory different for each environment,
     otherwise some unexpected behavior may happen. Each environment generates
diff --git a/console.rst b/console.rst
index 57f322c983d..6a3ba70300f 100644
--- a/console.rst
+++ b/console.rst
@@ -366,7 +366,7 @@ Output sections let you manipulate the Console output in advanced ways, such as
 are updated independently and :ref:`appending rows to tables <console-modify-rendered-tables>`
 that have already been rendered.
 
-.. caution::
+.. warning::
 
     Terminals only allow overwriting the visible content, so you must take into
     account the console height when trying to write/overwrite section contents.
@@ -531,13 +531,13 @@ call ``setAutoExit(false)`` on it to get the command result in ``CommandTester``
     You can also test a whole console application by using
     :class:`Symfony\\Component\\Console\\Tester\\ApplicationTester`.
 
-.. caution::
+.. warning::
 
     When testing commands using the ``CommandTester`` class, console events are
     not dispatched. If you need to test those events, use the
     :class:`Symfony\\Component\\Console\\Tester\\ApplicationTester` instead.
 
-.. caution::
+.. warning::
 
     When testing commands using the :class:`Symfony\\Component\\Console\\Tester\\ApplicationTester`
     class, don't forget to disable the auto exit flag::
@@ -547,7 +547,7 @@ call ``setAutoExit(false)`` on it to get the command result in ``CommandTester``
 
         $tester = new ApplicationTester($application);
 
-.. caution::
+.. warning::
 
     When testing ``InputOption::VALUE_NONE`` command options, you must pass ``true``
     to them::
@@ -619,7 +619,7 @@ profile is accessible through the web page of the profiler.
     terminal supports links). If you run it in debug verbosity (``-vvv``) you'll
     also see the time and memory consumed by the command.
 
-.. caution::
+.. warning::
 
     When profiling the ``messenger:consume`` command from the :doc:`Messenger </messenger>`
     component, add the ``--no-reset`` option to the command or you won't get any
diff --git a/console/calling_commands.rst b/console/calling_commands.rst
index c5bfc6e5a72..349f1357682 100644
--- a/console/calling_commands.rst
+++ b/console/calling_commands.rst
@@ -36,6 +36,9 @@ method)::
                 '--yell'  => true,
             ]);
 
+            // disable interactive behavior for the greet command
+            $greetInput->setInteractive(false);
+
             $returnCode = $this->getApplication()->doRun($greetInput, $output);
 
             // ...
@@ -57,7 +60,7 @@ method)::
     ``$this->getApplication()->find('demo:greet')->run()`` will allow proper
     events to be dispatched for that inner command as well.
 
-.. caution::
+.. warning::
 
     Note that all the commands will run in the same process and some of Symfony's
     built-in commands may not work well this way. For instance, the ``cache:clear``
diff --git a/console/command_in_controller.rst b/console/command_in_controller.rst
index 64475bff103..74af9e17c15 100644
--- a/console/command_in_controller.rst
+++ b/console/command_in_controller.rst
@@ -11,7 +11,7 @@ service that can be reused in the controller. However, when the command is part
 of a third-party library, you don't want to modify or duplicate their code.
 Instead, you can run the command directly from the controller.
 
-.. caution::
+.. warning::
 
     In comparison with a direct call from the console, calling a command from
     a controller has a slight performance impact because of the request stack
diff --git a/console/commands_as_services.rst b/console/commands_as_services.rst
index 75aa13d5be8..1393879a1df 100644
--- a/console/commands_as_services.rst
+++ b/console/commands_as_services.rst
@@ -51,7 +51,7 @@ argument (thanks to autowiring). In other words, you only need to create this
 class and everything works automatically! You can call the ``app:sunshine``
 command and start logging.
 
-.. caution::
+.. warning::
 
     You *do* have access to services in ``configure()``. However, if your command is
     not :ref:`lazy <console-command-service-lazy-loading>`, try to avoid doing any
@@ -130,7 +130,7 @@ only when the ``app:sunshine`` command is actually called.
 
     You don't need to call ``setName()`` for configuring the command when it is lazy.
 
-.. caution::
+.. warning::
 
     Calling the ``list`` command will instantiate all commands, including lazy commands.
     However, if the command is a ``Symfony\Component\Console\Command\LazyCommand``, then
diff --git a/console/input.rst b/console/input.rst
index c038ace56fc..baf47c6fd15 100644
--- a/console/input.rst
+++ b/console/input.rst
@@ -197,7 +197,7 @@ values after a whitespace or an ``=`` sign (e.g. ``--iterations 5`` or
 ``--iterations=5``), but short options can only use whitespaces or no
 separation at all (e.g. ``-i 5`` or ``-i5``).
 
-.. caution::
+.. warning::
 
     While it is possible to separate an option from its value with a whitespace,
     using this form leads to an ambiguity should the option appear before the
diff --git a/contributing/code/bc.rst b/contributing/code/bc.rst
index cff99a1554f..497c70fb01d 100644
--- a/contributing/code/bc.rst
+++ b/contributing/code/bc.rst
@@ -30,7 +30,7 @@ The second section, "Working on Symfony Code", is targeted at Symfony
 contributors. This section lists detailed rules that every contributor needs to
 follow to ensure smooth upgrades for our users.
 
-.. caution::
+.. warning::
 
     :doc:`Experimental Features </contributing/code/experimental>` and code
     marked with the ``@internal`` tags are excluded from our Backward
@@ -53,7 +53,7 @@ All interfaces shipped with Symfony can be used in type hints. You can also call
 any of the methods that they declare. We guarantee that we won't break code that
 sticks to these rules.
 
-.. caution::
+.. warning::
 
     The exception to this rule are interfaces tagged with ``@internal``. Such
     interfaces should not be used or implemented.
@@ -89,7 +89,7 @@ Using our Classes
 All classes provided by Symfony may be instantiated and accessed through their
 public methods and properties.
 
-.. caution::
+.. warning::
 
     Classes, properties and methods that bear the tag ``@internal`` as well as
     the classes located in the various ``*\Tests\`` namespaces are an
@@ -146,7 +146,7 @@ Using our Traits
 
 All traits provided by Symfony may be used in your classes.
 
-.. caution::
+.. warning::
 
     The exception to this rule are traits tagged with ``@internal``. Such
     traits should not be used.
diff --git a/contributing/code/bugs.rst b/contributing/code/bugs.rst
index fba68617ee3..b0a46766026 100644
--- a/contributing/code/bugs.rst
+++ b/contributing/code/bugs.rst
@@ -4,7 +4,7 @@ Reporting a Bug
 Whenever you find a bug in Symfony, we kindly ask you to report it. It helps
 us make a better Symfony.
 
-.. caution::
+.. warning::
 
     If you think you've found a security issue, please use the special
     :doc:`procedure <security>` instead.
diff --git a/contributing/code/maintenance.rst b/contributing/code/maintenance.rst
index 04740ce8c6e..27e4fd73ea0 100644
--- a/contributing/code/maintenance.rst
+++ b/contributing/code/maintenance.rst
@@ -67,6 +67,9 @@ issue):
 * **Adding new deprecations**: After a version reaches stability, new
   deprecations cannot be added anymore.
 
+* **Adding or updating annotations**: Adding or updating annotations (PHPDoc
+  annotations for instance) is not allowed; fixing them might be accepted.
+
 Anything not explicitly listed above should be done on the next minor or major
 version instead. For instance, the following changes are never accepted in a
 patch version:
diff --git a/contributing/documentation/format.rst b/contributing/documentation/format.rst
index d933f3bcead..e81abe92b79 100644
--- a/contributing/documentation/format.rst
+++ b/contributing/documentation/format.rst
@@ -16,7 +16,7 @@ source code.
 If you want to learn more about this format, check out the `reStructuredText Primer`_
 tutorial and the `reStructuredText Reference`_.
 
-.. caution::
+.. warning::
 
     If you are familiar with Markdown, be careful as things are sometimes very
     similar but different:
diff --git a/contributing/documentation/standards.rst b/contributing/documentation/standards.rst
index 420780d25f5..5e195d008fd 100644
--- a/contributing/documentation/standards.rst
+++ b/contributing/documentation/standards.rst
@@ -122,7 +122,7 @@ Example
         }
     }
 
-.. caution::
+.. warning::
 
     In YAML you should put a space after ``{`` and before ``}`` (e.g. ``{ _controller: ... }``),
     but this should not be done in Twig (e.g.  ``{'hello' : 'value'}``).
diff --git a/controller.rst b/controller.rst
index 4fd03948ae2..026e76ed0a6 100644
--- a/controller.rst
+++ b/controller.rst
@@ -443,6 +443,26 @@ HTTP status to return if the validation fails::
 
 The default status code returned if the validation fails is 404.
 
+If you want to map your object to a nested array in your query using a specific key,
+set the ``key`` option in the ``#[MapQueryString]`` attribute::
+
+    use App\Model\SearchDto;
+    use Symfony\Component\HttpFoundation\Response;
+    use Symfony\Component\HttpKernel\Attribute\MapQueryString;
+
+    // ...
+
+    public function dashboard(
+        #[MapQueryString(key: 'search')] SearchDto $searchDto
+    ): Response
+    {
+        // ...
+    }
+
+.. versionadded:: 7.3
+
+    The ``key`` option of ``#[MapQueryString]`` was introduced in Symfony 7.3.
+
 If you need a valid DTO even when the request query string is empty, set a
 default value for your controller arguments::
 
@@ -788,6 +808,14 @@ response types.  Some of these are mentioned below. To learn more about the
 ``Request`` and ``Response`` (and different ``Response`` classes), see the
 :ref:`HttpFoundation component documentation <component-http-foundation-request>`.
 
+.. note::
+
+    Technically, a controller can return a value other than a ``Response``.
+    However, your application is responsible for transforming that value into a
+    ``Response`` object. This is handled using :doc:`events </event_dispatcher>`
+    (specifically the :ref:`kernel.view event <component-http-kernel-kernel-view>`),
+    an advanced feature you'll learn about later.
+
 Accessing Configuration Values
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -890,7 +918,7 @@ method::
         {
             $response = $this->sendEarlyHints([
                 new Link(rel: 'preconnect', href: 'https://fonts.google.com'),
-                (new Link(href: '/style.css'))->withAttribute('as', 'stylesheet'),
+                (new Link(href: '/style.css'))->withAttribute('as', 'style'),
                 (new Link(href: '/script.js'))->withAttribute('as', 'script'),
             ]);
 
@@ -946,6 +974,6 @@ Learn more about Controllers
 .. _`Early hints`: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103
 .. _`SAPI`: https://www.php.net/manual/en/function.php-sapi-name.php
 .. _`FrankenPHP`: https://frankenphp.dev
-.. _`Validate Filters`: https://www.php.net/manual/en/filter.filters.validate.php
+.. _`Validate Filters`: https://www.php.net/manual/en/filter.constants.php
 .. _`phpstan/phpdoc-parser`: https://packagist.org/packages/phpstan/phpdoc-parser
 .. _`phpdocumentor/type-resolver`: https://packagist.org/packages/phpdocumentor/type-resolver
diff --git a/controller/error_pages.rst b/controller/error_pages.rst
index 001e637c03e..fc36b88779a 100644
--- a/controller/error_pages.rst
+++ b/controller/error_pages.rst
@@ -319,7 +319,7 @@ error pages.
 
 .. note::
 
-    If your listener calls ``setThrowable()`` on the
+    If your listener calls ``setResponse()`` on the
     :class:`Symfony\\Component\\HttpKernel\\Event\\ExceptionEvent`
     event, propagation will be stopped and the response will be sent to
     the client.
diff --git a/deployment.rst b/deployment.rst
index 3edbc34dd6b..864ebc7a963 100644
--- a/deployment.rst
+++ b/deployment.rst
@@ -184,7 +184,7 @@ as you normally do:
     significantly by building a "class map". The ``--no-dev`` flag ensures that
     development packages are not installed in the production environment.
 
-.. caution::
+.. warning::
 
     If you get a "class not found" error during this step, you may need to
     run ``export APP_ENV=prod`` (or ``export SYMFONY_ENV=prod`` if you're not
diff --git a/deployment/proxies.rst b/deployment/proxies.rst
index cd5649d979a..4dad6f95fb1 100644
--- a/deployment/proxies.rst
+++ b/deployment/proxies.rst
@@ -102,7 +102,7 @@ using the following configuration options:
     Support for the ``SYMFONY_TRUSTED_PROXIES`` and ``SYMFONY_TRUSTED_HEADERS``
     environment variables was introduced in Symfony 7.2.
 
-.. caution::
+.. danger::
 
     Enabling the ``Request::HEADER_X_FORWARDED_HOST`` option exposes the
     application to `HTTP Host header attacks`_. Make sure the proxy really
diff --git a/doctrine.rst b/doctrine.rst
index dc42a5b9e73..171f8a3348a 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -58,7 +58,7 @@ The database connection information is stored as an environment variable called
     # to use oracle:
     # DATABASE_URL="oci8://db_user:db_password@127.0.0.1:1521/db_name"
 
-.. caution::
+.. warning::
 
     If the username, password, host or database name contain any character considered
     special in a URI (such as ``: / ? # [ ] @ ! $ & ' ( ) * + , ; =``),
@@ -174,7 +174,7 @@ Whoa! You now have a new ``src/Entity/Product.php`` file::
     Confused why the price is an integer? Don't worry: this is just an example.
     But, storing prices as integers (e.g. 100 = $1 USD) can avoid rounding issues.
 
-.. caution::
+.. warning::
 
     There is a `limit of 767 bytes for the index key prefix`_ when using
     InnoDB tables in MySQL 5.6 and earlier versions. String columns with 255
@@ -204,7 +204,7 @@ If you want to use XML instead of attributes, add ``type: xml`` and
 ``dir: '%kernel.project_dir%/config/doctrine'`` to the entity mappings in your
 ``config/packages/doctrine.yaml`` file.
 
-.. caution::
+.. warning::
 
     Be careful not to use reserved SQL keywords as your table or column names
     (e.g. ``GROUP`` or ``USER``). See Doctrine's `Reserved SQL keywords documentation`_
@@ -320,7 +320,7 @@ before, execute your migrations:
 
     $ php bin/console doctrine:migrations:migrate
 
-.. caution::
+.. warning::
 
     If you are using an SQLite database, you'll see the following error:
     *PDOException: SQLSTATE[HY000]: General error: 1 Cannot add a NOT NULL
diff --git a/doctrine/custom_dql_functions.rst b/doctrine/custom_dql_functions.rst
index 1b3aa4aa185..e5b21819f58 100644
--- a/doctrine/custom_dql_functions.rst
+++ b/doctrine/custom_dql_functions.rst
@@ -132,7 +132,7 @@ In Symfony, you can register your custom DQL functions as follows:
                             ->datetimeFunction('test_datetime', DatetimeFunction::class);
             };
 
-.. caution::
+.. warning::
 
     DQL functions are instantiated by Doctrine outside of the Symfony
     :doc:`service container </service_container>` so you can't inject services
diff --git a/doctrine/multiple_entity_managers.rst b/doctrine/multiple_entity_managers.rst
index 014d9e4dccb..1a56c55ddad 100644
--- a/doctrine/multiple_entity_managers.rst
+++ b/doctrine/multiple_entity_managers.rst
@@ -15,7 +15,7 @@ entities, each with their own database connection strings or separate cache conf
     advanced and not usually required. Be sure you actually need multiple
     entity managers before adding in this layer of complexity.
 
-.. caution::
+.. warning::
 
     Entities cannot define associations across different entity managers. If you
     need that, there are `several alternatives`_ that require some custom setup.
@@ -142,7 +142,7 @@ and ``customer``. The ``default`` entity manager manages entities in the
 entities in ``src/Entity/Customer``. You've also defined two connections, one
 for each entity manager, but you are free to define the same connection for both.
 
-.. caution::
+.. warning::
 
     When working with multiple connections and entity managers, you should be
     explicit about which configuration you want. If you *do* omit the name of
@@ -251,7 +251,7 @@ The same applies to repository calls::
         }
     }
 
-.. caution::
+.. warning::
 
     One entity can be managed by more than one entity manager. This however
     results in unexpected behavior when extending from ``ServiceEntityRepository``
diff --git a/event_dispatcher.rst b/event_dispatcher.rst
index 6787cba2d83..27885af267b 100644
--- a/event_dispatcher.rst
+++ b/event_dispatcher.rst
@@ -41,6 +41,9 @@ The most common way to listen to an event is to register an **event listener**::
             // Customize your response object to display the exception details
             $response = new Response();
             $response->setContent($message);
+            // the exception message can contain unfiltered user input;
+            // set the content-type to text to avoid XSS issues
+            $response->headers->set('Content-Type', 'text/plain; charset=utf-8');
 
             // HttpExceptionInterface is a special type of exception that
             // holds status code and header details
@@ -798,3 +801,11 @@ could listen to the ``mailer.post_send`` event and change the method's return va
 
 That's it! Your subscriber should be called automatically (or read more about
 :ref:`event subscriber configuration <ref-event-subscriber-configuration>`).
+
+Learn More
+----------
+
+- :ref:`The Request-Response Lifecycle <the-workflow-of-a-request>`
+- :doc:`/reference/events`
+- :ref:`Security-related Events <security-security-events>`
+- :doc:`/components/event_dispatcher`
diff --git a/form/bootstrap5.rst b/form/bootstrap5.rst
index 400747bba12..db098a1ba09 100644
--- a/form/bootstrap5.rst
+++ b/form/bootstrap5.rst
@@ -171,7 +171,7 @@ class to the label:
         ],
         // ...
 
-.. caution::
+.. warning::
 
     Switches only work with **checkbox**.
 
@@ -201,7 +201,7 @@ class to the ``row_attr`` option.
             }
         }) }}
 
-.. caution::
+.. warning::
 
     If you fill the ``help`` option of your form, it will also be rendered
     as part of the group.
@@ -239,7 +239,7 @@ of your form type.
             }
         }) }}
 
-.. caution::
+.. warning::
 
     You **must** provide a ``label`` and a ``placeholder`` to make floating
     labels work properly.
diff --git a/form/create_custom_field_type.rst b/form/create_custom_field_type.rst
index 709f3321544..0d92a967fa0 100644
--- a/form/create_custom_field_type.rst
+++ b/form/create_custom_field_type.rst
@@ -449,7 +449,7 @@ are some examples of Twig block names for the postal address type:
 ``postal_address_zipCode_label``
     The label block of the ZIP Code field.
 
-.. caution::
+.. warning::
 
     When the name of your form class matches any of the built-in field types,
     your form might not be rendered correctly. A form type named
diff --git a/form/data_mappers.rst b/form/data_mappers.rst
index cb5c7936701..38c92ce35ae 100644
--- a/form/data_mappers.rst
+++ b/form/data_mappers.rst
@@ -126,7 +126,7 @@ in your form type::
         }
     }
 
-.. caution::
+.. warning::
 
     The data passed to the mapper is *not yet validated*. This means that your
     objects should allow being created in an invalid state in order to produce
@@ -215,7 +215,7 @@ If available, these options have priority over the property path accessor and
 the default data mapper will still use the :doc:`PropertyAccess component </components/property_access>`
 for the other form fields.
 
-.. caution::
+.. warning::
 
     When a form has the ``inherit_data`` option set to ``true``, it does not use the data mapper and
     lets its parent map inner values.
diff --git a/form/data_transformers.rst b/form/data_transformers.rst
index 4e81fc3e930..db051a04bbc 100644
--- a/form/data_transformers.rst
+++ b/form/data_transformers.rst
@@ -8,7 +8,7 @@ can be rendered as a ``yyyy-MM-dd``-formatted input text box. Internally, a data
 converts the ``DateTime`` value of the field to a ``yyyy-MM-dd`` formatted string
 when rendering the form, and then back to a ``DateTime`` object on submit.
 
-.. caution::
+.. warning::
 
     When a form field has the ``inherit_data`` option set to ``true``, data transformers
     are not applied to that field.
@@ -340,7 +340,7 @@ that, after a successful submission, the Form component will pass a real
 If the issue isn't found, a form error will be created for that field and
 its error message can be controlled with the ``invalid_message`` field option.
 
-.. caution::
+.. warning::
 
     Be careful when adding your transformers. For example, the following is **wrong**,
     as the transformer would be applied to the entire form, instead of just this
@@ -472,7 +472,7 @@ Which transformer you need depends on your situation.
 
 To use the view transformer, call ``addViewTransformer()``.
 
-.. caution::
+.. warning::
 
     Be careful with model transformers and
     :doc:`Collection </reference/forms/types/collection>` field types.
diff --git a/form/direct_submit.rst b/form/direct_submit.rst
index 7b98134af18..7a08fb6978a 100644
--- a/form/direct_submit.rst
+++ b/form/direct_submit.rst
@@ -65,7 +65,7 @@ the fields defined by the form class. Otherwise, you'll see a form validation er
     argument to ``submit()``. Passing ``false`` will remove any missing fields
     within the form object. Otherwise, the missing fields will be set to ``null``.
 
-.. caution::
+.. warning::
 
     When the second parameter ``$clearMissing`` is ``false``, like with the
     "PATCH" method, the validation will only apply to the submitted fields. If
diff --git a/form/events.rst b/form/events.rst
index 745df2df453..dad6c242ddd 100644
--- a/form/events.rst
+++ b/form/events.rst
@@ -192,7 +192,7 @@ Form view data        Same as in ``FormEvents::POST_SET_DATA``
     See all form events at a glance in the
     :ref:`Form Events Information Table <component-form-event-table>`.
 
-.. caution::
+.. warning::
 
     At this point, you cannot add or remove fields to the form.
 
@@ -225,7 +225,7 @@ Form view data        Normalized data transformed using a view transformer
     See all form events at a glance in the
     :ref:`Form Events Information Table <component-form-event-table>`.
 
-.. caution::
+.. warning::
 
     At this point, you cannot add or remove fields to the current form and its
     children.
diff --git a/form/form_collections.rst b/form/form_collections.rst
index f0ad76a8a61..2a0ba99657f 100644
--- a/form/form_collections.rst
+++ b/form/form_collections.rst
@@ -195,7 +195,7 @@ then set on the ``tag`` field of the ``Task`` and can be accessed via ``$task->g
 So far, this works great, but only to edit *existing* tags. It doesn't allow us
 yet to add new tags or delete existing ones.
 
-.. caution::
+.. warning::
 
     You can embed nested collections as many levels down as you like. However,
     if you use Xdebug, you may receive a ``Maximum function nesting level of '100'
@@ -427,13 +427,13 @@ That was fine, but forcing the use of the "adder" method makes handling
 these new ``Tag`` objects easier (especially if you're using Doctrine, which
 you will learn about next!).
 
-.. caution::
+.. warning::
 
     You have to create **both** ``addTag()`` and ``removeTag()`` methods,
     otherwise the form will still use ``setTag()`` even if ``by_reference`` is ``false``.
     You'll learn more about the ``removeTag()`` method later in this article.
 
-.. caution::
+.. warning::
 
     Symfony can only make the plural-to-singular conversion (e.g. from the
     ``tags`` property to the ``addTag()`` method) for English words. Code
diff --git a/form/form_customization.rst b/form/form_customization.rst
index 3f3cd0bbc89..1c23601a883 100644
--- a/form/form_customization.rst
+++ b/form/form_customization.rst
@@ -74,7 +74,7 @@ control over how each form field is rendered, so you can fully customize them:
         </div>
     </div>
 
-.. caution::
+.. warning::
 
    If you're rendering each field manually, make sure you don't forget the
    ``_token`` field that is automatically added for CSRF protection.
@@ -305,7 +305,7 @@ Renders any errors for the given field.
     {# render any "global" errors not associated to any form field #}
     {{ form_errors(form) }}
 
-.. caution::
+.. warning::
 
     In the Bootstrap 4 form theme, ``form_errors()`` is already included in
     ``form_label()``. Read more about this in the
diff --git a/form/form_themes.rst b/form/form_themes.rst
index eb6f6f2ae22..8b82982edaa 100644
--- a/form/form_themes.rst
+++ b/form/form_themes.rst
@@ -177,7 +177,7 @@ of form themes:
 
     {# ... #}
 
-.. caution::
+.. warning::
 
     When using the ``only`` keyword, none of Symfony's built-in form themes
     (``form_div_layout.html.twig``, etc.) will be applied. In order to render
diff --git a/form/inherit_data_option.rst b/form/inherit_data_option.rst
index 19b14b27bcd..2caa0afcdbe 100644
--- a/form/inherit_data_option.rst
+++ b/form/inherit_data_option.rst
@@ -165,6 +165,6 @@ Finally, make this work by adding the location form to your two original forms::
 That's it! You have extracted duplicated field definitions to a separate
 location form that you can reuse wherever you need it.
 
-.. caution::
+.. warning::
 
     Forms with the ``inherit_data`` option set cannot have ``*_SET_DATA`` event listeners.
diff --git a/form/type_guesser.rst b/form/type_guesser.rst
index 111f1b77986..106eb4e7742 100644
--- a/form/type_guesser.rst
+++ b/form/type_guesser.rst
@@ -162,7 +162,7 @@ instance with the value of the option. This constructor has 2 arguments:
 ``null`` is guessed when you believe the value of the option should not be
 set.
 
-.. caution::
+.. warning::
 
     You should be very careful using the ``guessMaxLength()`` method. When the
     type is a float, you cannot determine a length (e.g. you want a float to be
diff --git a/form/unit_testing.rst b/form/unit_testing.rst
index bf57e6d1afc..9603c5bc0d2 100644
--- a/form/unit_testing.rst
+++ b/form/unit_testing.rst
@@ -1,7 +1,7 @@
 How to Unit Test your Forms
 ===========================
 
-.. caution::
+.. warning::
 
     This article is intended for developers who create
     :doc:`custom form types </form/create_custom_field_type>`. If you are using
@@ -121,7 +121,7 @@ variable exists and will be available in your form themes::
     Use `PHPUnit data providers`_ to test multiple form conditions using
     the same test code.
 
-.. caution::
+.. warning::
 
     When your type relies on the ``EntityType``, you should register the
     :class:`Symfony\\Bridge\\Doctrine\\Form\\DoctrineOrmExtension`, which will
@@ -214,7 +214,7 @@ allows you to return a list of extensions to register::
         {
             $validator = Validation::createValidator();
 
-            // or if you also need to read constraints from annotations
+            // or if you also need to read constraints from attributes
             $validator = Validation::createValidatorBuilder()
                 ->enableAttributeMapping()
                 ->getValidator();
diff --git a/form/without_class.rst b/form/without_class.rst
index 589f8a4739e..436976bdfcc 100644
--- a/form/without_class.rst
+++ b/form/without_class.rst
@@ -121,7 +121,7 @@ but here's a short example::
     submitted data is validated using the ``Symfony\Component\Validator\Constraints\Valid``
     constraint, unless you :doc:`disable validation </form/disabling_validation>`.
 
-.. caution::
+.. warning::
 
     When a form is only partially submitted (for example, in an HTTP PATCH
     request), only the constraints from the submitted form fields will be
diff --git a/forms.rst b/forms.rst
index a90e4ee1772..008c60a66c6 100644
--- a/forms.rst
+++ b/forms.rst
@@ -869,7 +869,7 @@ pass ``null`` to it::
         }
     }
 
-.. caution::
+.. warning::
 
     When using a specific :doc:`form validation group </form/validation_groups>`,
     the field type guesser will still consider *all* validation constraints when
diff --git a/frontend.rst b/frontend.rst
index f498dc737b5..c28e6fcf222 100644
--- a/frontend.rst
+++ b/frontend.rst
@@ -61,6 +61,10 @@ be executed by a browser.
 AssetMapper (Recommended)
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
+.. screencast::
+
+    Do you prefer video tutorials? Check out the `AssetMapper screencast series`_.
+
 AssetMapper is the recommended system for handling your assets. It runs entirely
 in PHP with no complex build step or dependencies. It does this by leveraging
 the ``importmap`` feature of your browser, which is available in all browsers thanks
@@ -118,6 +122,10 @@ the `StimulusBundle Documentation`_
 Using a Front-end Framework (React, Vue, Svelte, etc)
 -----------------------------------------------------
 
+.. screencast::
+
+    Do you prefer video tutorials? Check out the `API Platform screencast series`_.
+
 If you want to use a front-end framework (Next.js, React, Vue, Svelte, etc),
 we recommend using their native tools and using Symfony as a pure API. A wonderful
 tool to do that is `API Platform`_. Their standard distribution comes with a
@@ -143,3 +151,5 @@ Other Front-End Articles
 .. _`Symfony UX`: https://ux.symfony.com
 .. _`API Platform`: https://api-platform.com/
 .. _`SensioLabs Minify Bundle`: https://github.com/sensiolabs/minify-bundle
+.. _`AssetMapper screencast series`: https://symfonycasts.com/screencast/asset-mapper
+.. _`API Platform screencast series`: https://symfonycasts.com/screencast/api-platform
diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index 685474e66d3..d68c77c0105 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -12,7 +12,7 @@ The component has two main features:
 * :ref:`Mapping & Versioning Assets <mapping-assets>`: All files inside of ``assets/``
   are made available publicly and **versioned**. You can reference the file
   ``assets/images/product.jpg`` in a Twig template with ``{{ asset('images/product.jpg') }}``.
-  The final URL will include a version hash, like ``/assets/images/product-3c16d9220694c0e56d8648f25e6035e9.jpg``.
+  The final URL will include a version hash, like ``/assets/images/product-3c16d92m.jpg``.
 
 * :ref:`Importmaps <importmaps-javascript>`: A native browser feature that makes it easier
   to use the JavaScript ``import`` statement (e.g. ``import { Modal } from 'bootstrap'``)
@@ -70,7 +70,7 @@ The path - ``images/duck.png`` - is relative to your mapped directory (``assets/
 This is known as the **logical path** to your asset.
 
 If you look at the HTML in your page, the URL will be something
-like: ``/assets/images/duck-3c16d9220694c0e56d8648f25e6035e9.png``. If you change
+like: ``/assets/images/duck-3c16d92m.png``. If you change
 the file, the version part of the URL will also change automatically.
 
 .. _asset-mapper-compile-assets:
@@ -78,7 +78,7 @@ the file, the version part of the URL will also change automatically.
 Serving Assets in dev vs prod
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-In the ``dev`` environment, the URL ``/assets/images/duck-3c16d9220694c0e56d8648f25e6035e9.png``
+In the ``dev`` environment, the URL ``/assets/images/duck-3c16d92m.png``
 is handled and returned by your Symfony app.
 
 For the ``prod`` environment, before deploy, you should run:
@@ -91,7 +91,7 @@ This will physically copy all the files from your mapped directories to
 ``public/assets/`` so that they're served directly by your web server.
 See :ref:`Deployment <asset-mapper-deployment>` for more details.
 
-.. caution::
+.. warning::
 
     If you run the ``asset-map:compile`` command on your development machine,
     you won't see any changes made to your assets when reloading the page.
@@ -283,9 +283,9 @@ outputs an `importmap`_:
 
     <script type="importmap">{
         "imports": {
-            "app": "/assets/app-4e986c1a2318dd050b1d47db8d856278.js",
-            "/assets/duck.js": "/assets/duck-1b7a64b3b3d31219c262cf72521a5267.js",
-            "bootstrap": "/assets/vendor/bootstrap/bootstrap.index-f0935445d9c6022100863214b519a1f2.js"
+            "app": "/assets/app-4e986c1a.js",
+            "/assets/duck.js": "/assets/duck-1b7a64b3.js",
+            "bootstrap": "/assets/vendor/bootstrap/bootstrap.index-f093544d.js"
         }
     }</script>
 
@@ -342,8 +342,8 @@ The ``importmap()`` function also outputs a set of "preloads":
 
 .. code-block:: html
 
-    <link rel="modulepreload" href="/assets/app-4e986c1a2318dd050b1d47db8d856278.js">
-    <link rel="modulepreload" href="/assets/duck-1b7a64b3b3d31219c262cf72521a5267.js">
+    <link rel="modulepreload" href="/assets/app-4e986c1a.js">
+    <link rel="modulepreload" href="/assets/duck-1b7a64b3.js">
 
 This is a performance optimization and you can learn more about below
 in :ref:`Performance: Add Preloading <performance-preloading>`.
@@ -415,6 +415,8 @@ from inside ``app.js``:
     // things on "window" become global variables
     window.$ = $;
 
+.. _asset-mapper-handling-css:
+
 Handling CSS
 ------------
 
@@ -492,9 +494,9 @@ for ``duck.png``:
 
 .. code-block:: css
 
-    /* public/assets/styles/app-3c16d9220694c0e56d8648f25e6035e9.css */
+    /* public/assets/styles/app-3c16d92m.css */
     .quack {
-        background-image: url('../images/duck-3c16d9220694c0e56d8648f25e6035e9.png');
+        background-image: url('../images/duck-3c16d92m.png');
     }
 
 .. _asset-mapper-tailwind:
@@ -571,7 +573,7 @@ Sometimes a JavaScript file you're importing (e.g. ``import './duck.js'``),
 or a CSS/image file you're referencing won't be found, and you'll see a 404
 error in your browser's console. You'll also notice that the 404 URL is missing
 the version hash in the filename (e.g. a 404 to ``/assets/duck.js`` instead of
-a path like ``/assets/duck.1b7a64b3b3d31219c262cf72521a5267.js``).
+a path like ``/assets/duck-1b7a64b3.js``).
 
 This is usually because the path is wrong. If you're referencing the file
 directly in a Twig template:
@@ -646,7 +648,7 @@ To make your AssetMapper-powered site fly, there are a few things you need to
 do. If you want to take a shortcut, you can use a service like `Cloudflare`_,
 which will automatically do most of these things for you:
 
-- **Use HTTP/2**: Your web server should be running HTTP/2 (or HTTP/3) so the
+- **Use HTTP/2**: Your web server should be running HTTP/2 or HTTP/3 so the
   browser can download assets in parallel. HTTP/2 is automatically enabled in Caddy
   and can be activated in Nginx and Apache. Or, proxy your site through a
   service like Cloudflare, which will automatically enable HTTP/2 for you.
@@ -654,7 +656,9 @@ which will automatically do most of these things for you:
 - **Compress your assets**: Your web server should compress (e.g. using gzip)
   your assets (JavaScript, CSS, images) before sending them to the browser. This
   is automatically enabled in Caddy and can be activated in Nginx and Apache.
-  In Cloudflare, assets are compressed by default.
+  In Cloudflare, assets are compressed by default. AssetMapper also supports
+  :ref:`precompressing your web assets <performance-precompressing>` to further
+  improve performance.
 
 - **Set long-lived cache expiry**: Your web server should set a long-lived
   ``Cache-Control`` HTTP header on your assets. Because the AssetMapper component includes a version
@@ -702,6 +706,76 @@ even though it hasn't yet seen the ``import`` statement for them.
 Additionally, if the :doc:`WebLink Component </web_link>` is available in your application,
 Symfony will add a ``Link`` header in the response to preload the CSS files.
 
+.. _performance-precompressing:
+
+Pre-Compressing Assets
+----------------------
+
+Although most servers (Caddy, Nginx, Apache, FrankenPHP) and services like Cloudflare
+provide asset compression features, AssetMapper also allows you to compress all
+your assets before serving them.
+
+This improves performance because you can compress assets using the highest (and
+slowest) compression ratios beforehand and provide those compressed assets to the
+server, which then returns them to the client without wasting CPU resources on
+compression.
+
+AssetMapper supports  `Brotli`_, `Zstandard`_ and  `gzip`_ compression formats.
+Before using any of them, the server that pre-compresses assets must have
+installed the following PHP extensions or CLI commands:
+
+* Brotli: ``brotli`` CLI command; `brotli PHP extension`_;
+* Zstandard: ``zstd`` CLI command; `zstd PHP extension`_;
+* gzip: ``zopfli`` (better) or ``gzip`` CLI command; `zlib PHP extension`_.
+
+Then, update your AssetMapper configuration to define which compression to use
+and which file extensions should be compressed:
+
+.. code-block:: yaml
+
+    # config/packages/asset_mapper.yaml
+    framework:
+        asset_mapper:
+            # ...
+
+            precompress:
+                format: 'zstandard'
+                # if you don't define the following option, AssetMapper will compress all
+                # the extensions considered safe (css, js, json, svg, xml, ttf, otf, wasm, etc.)
+                extensions: ['css', 'js', 'json', 'svg', 'xml']
+
+Now, when running the ``asset-map:compile`` command, all matching files will be
+compressed in the configured format and at the highest compression level. The
+compressed files are created with the same name as the original but with the
+``.br``, ``.zst``, or ``.gz`` extension appended.
+
+Then, you need to configure your web server to serve the precompressed assets
+instead of the original ones:
+
+.. configuration-block::
+
+    .. code-block:: caddy
+
+        file_server {
+            precompressed br zstd gzip
+        }
+
+    .. code-block:: nginx
+
+        gzip_static on;
+
+        # Requires https://github.com/google/ngx_brotli
+        brotli_static on;
+
+        # Requires https://github.com/tokers/zstd-nginx-module
+        zstd_static on;
+
+.. tip::
+
+    AssetMapper provides an ``assets:compress`` CLI command and a service called
+    ``asset_mapper.compressor`` that you can use anywhere in your application to
+    compress any kind of files (e.g. files uploaded by users to your application).
+
 Frequently Asked Questions
 --------------------------
 
@@ -846,7 +920,7 @@ be versioned! It will output something like:
 
 .. code-block:: html+twig
 
-    <link rel="stylesheet" href="/assets/bundles/babdevpagerfanta/css/pagerfanta-ea64fc9c55f8394e696554f8aeb81a8e.css">
+    <link rel="stylesheet" href="/assets/bundles/babdevpagerfanta/css/pagerfanta-ea64fc9c.css">
 
 Overriding 3rd-Party Assets
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1093,6 +1167,24 @@ it in the CSP header, and then pass the same nonce to the Twig function:
     {# the csp_nonce() function is defined by the NelmioSecurityBundle #}
     {{ importmap('app', {'nonce': csp_nonce('script')}) }}
 
+Content Security Policy and CSS Files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If your importmap includes CSS files, AssetMapper uses a trick to load those by
+adding ``data:application/javascript`` to the rendered importmap (see
+:ref:`Handling CSS <asset-mapper-handling-css>`).
+
+This can cause browsers to report CSP violations and block the CSS files from
+being loaded. To prevent this, you can add `strict-dynamic`_ to the ``script-src``
+directive of your Content Security Policy, to tell the browser that the importmap
+is allowed to load other resources.
+
+.. note::
+
+    When using ``strict-dynamic``, the browser will ignore any other sources in
+    ``script-src`` such as ``'self'`` or ``'unsafe-inline'``, so any other
+    ``<script>`` tags will also need to be trusted via a nonce.
+
 The AssetMapper Component Caching System in dev
 -----------------------------------------------
 
@@ -1172,5 +1264,12 @@ command as part of your CI to be warned anytime a new vulnerability is found.
 .. _`package.json configuration file`: https://docs.npmjs.com/creating-a-package-json-file
 .. _Content Security Policy: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
 .. _NelmioSecurityBundle: https://symfony.com/bundles/NelmioSecurityBundle/current/index.html#nonce-for-inline-script-handling
+.. _strict-dynamic: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#strict-dynamic
 .. _kocal/biome-js-bundle: https://github.com/Kocal/BiomeJsBundle
 .. _`SensioLabs Minify Bundle`: https://github.com/sensiolabs/minify-bundle
+.. _`Brotli`: https://en.wikipedia.org/wiki/Brotli
+.. _`Zstandard`: https://en.wikipedia.org/wiki/Zstd
+.. _`gzip`: https://en.wikipedia.org/wiki/Gzip
+.. _`brotli PHP extension`: https://pecl.php.net/package/brotli
+.. _`zstd PHP extension`: https://pecl.php.net/package/zstd
+.. _`zlib PHP extension`: https://www.php.net/manual/en/book.zlib.php
diff --git a/frontend/encore/installation.rst b/frontend/encore/installation.rst
index f98ac8b75a0..2ddff9de345 100644
--- a/frontend/encore/installation.rst
+++ b/frontend/encore/installation.rst
@@ -200,7 +200,7 @@ You'll customize and learn more about these files in :doc:`/frontend/encore/simp
 When you execute Encore, it will ask you to install a few more dependencies based
 on which features of Encore you have enabled.
 
-.. caution::
+.. warning::
 
     Some of the documentation will use features that are specific to Symfony or
     Symfony's `WebpackEncoreBundle`_. These are optional, and are special ways
diff --git a/frontend/encore/simple-example.rst b/frontend/encore/simple-example.rst
index d790611b511..1c6c6b05c08 100644
--- a/frontend/encore/simple-example.rst
+++ b/frontend/encore/simple-example.rst
@@ -82,7 +82,7 @@ in your ``package.json`` file.
     in the :ref:`Symfony CLI Workers <symfony-server_configuring-workers>`
     documentation.
 
-.. caution::
+.. warning::
 
     Whenever you make changes in your ``webpack.config.js`` file, you must
     stop and restart ``encore``.
@@ -434,7 +434,7 @@ Your app now supports Sass. Encore also supports LESS and Stylus. See
 Compiling Only a CSS File
 -------------------------
 
-.. caution::
+.. warning::
 
     Using ``addStyleEntry()`` is supported, but not recommended. A better option
     is to follow the pattern above: use ``addEntry()`` to point to a JavaScript
diff --git a/frontend/encore/virtual-machine.rst b/frontend/encore/virtual-machine.rst
index c24d2b3670b..d18026d3633 100644
--- a/frontend/encore/virtual-machine.rst
+++ b/frontend/encore/virtual-machine.rst
@@ -87,7 +87,7 @@ connections:
           }
       }
 
-.. caution::
+.. danger::
 
     Make sure to run the development server inside your virtual machine only;
     otherwise other computers can have access to it.
@@ -110,7 +110,7 @@ the dev-server. To fix this, set the ``allowedHosts`` option:
             options.allowedHosts = all;
         })
 
-.. caution::
+.. warning::
 
     Beware that `it's not recommended to set allowedHosts to all`_ in general, but
     here it's required to solve the issue when using Encore in a virtual machine.
diff --git a/http_cache/cache_invalidation.rst b/http_cache/cache_invalidation.rst
index 4d5e07acc61..394c79aed42 100644
--- a/http_cache/cache_invalidation.rst
+++ b/http_cache/cache_invalidation.rst
@@ -14,7 +14,7 @@ cache lifetimes, but to actively notify the gateway cache when content
 changes. Reverse proxies usually provide a channel to receive such
 notifications, typically through special HTTP requests.
 
-.. caution::
+.. warning::
 
     While cache invalidation is powerful, avoid it when possible. If you fail
     to invalidate something, outdated caches will be served for a potentially
diff --git a/http_cache/esi.rst b/http_cache/esi.rst
index 52a09fb16a7..588cad424cd 100644
--- a/http_cache/esi.rst
+++ b/http_cache/esi.rst
@@ -259,7 +259,7 @@ One great advantage of the ESI renderer is that you can make your application
 as dynamic as needed and at the same time, hit the application as little as
 possible.
 
-.. caution::
+.. warning::
 
     The fragment listener only responds to signed requests. Requests are only
     signed when using the fragment renderer and the ``render_esi`` Twig
diff --git a/http_cache/varnish.rst b/http_cache/varnish.rst
index 3c1fa6d5346..a9bb668c100 100644
--- a/http_cache/varnish.rst
+++ b/http_cache/varnish.rst
@@ -44,6 +44,12 @@ header. In this case, you need to add the following configuration snippet:
         }
     }
 
+.. note::
+
+    Forcing HTTPS while using a reverse proxy or load balancer requires a proper
+    configuration to avoid infinite redirect loops; see :doc:`/deployment/proxies`
+    for more details.
+
 Cookies and Caching
 -------------------
 
@@ -61,24 +67,29 @@ at least for some parts of the site, e.g. when using forms with
 and clear the session when it is no longer needed. Alternatively, you can look
 into :ref:`caching pages that contain CSRF protected forms <caching-pages-that-contain-csrf-protected-forms>`.
 
-Cookies created in JavaScript and used only in the frontend, e.g. when using
-Google Analytics, are nonetheless sent to the server. These cookies are not
-relevant for the backend and should not affect the caching decision. Configure
-your Varnish cache to `clean the cookies header`_. You want to keep the
-session cookie, if there is one, and get rid of all other cookies so that pages
-are cached if there is no active session. Unless you changed the default
-configuration of PHP, your session cookie has the name ``PHPSESSID``:
+Cookies created in JavaScript and used only on the frontend, such as those from
+Google Analytics, are still sent to the server. These cookies are not relevant
+for backend processing and should not influence the caching logic. To ensure
+this, configure your Varnish cache to `clean the cookies header`_ by retaining
+only essential cookies (e.g., session cookies) and removing all others. This
+allows pages to be cached when there is no active session.
+
+If you are using PHP with its default configuration, the session cookie is
+typically named ``PHPSESSID``. Additionally, if your application depends on other
+critical cookies, such as a ``REMEMBERME`` cookie for :doc:`remember me </security/remember_me>`
+functionality or a trusted device cookie for two-factor authentication, these
+cookies should also be preserved.
 
 .. configuration-block::
 
     .. code-block:: varnish4
 
         sub vcl_recv {
-            // Remove all cookies except the session ID.
+            // Remove all cookies except for essential ones.
             if (req.http.Cookie) {
                 set req.http.Cookie = ";" + req.http.Cookie;
                 set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
-                set req.http.Cookie = regsuball(req.http.Cookie, ";(PHPSESSID)=", "; \1=");
+                set req.http.Cookie = regsuball(req.http.Cookie, ";(PHPSESSID|REMEMBERME)=", "; \1=");
                 set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
                 set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
 
@@ -92,11 +103,11 @@ configuration of PHP, your session cookie has the name ``PHPSESSID``:
     .. code-block:: varnish3
 
         sub vcl_recv {
-            // Remove all cookies except the session ID.
+            // Remove all cookies except for essential ones.
             if (req.http.Cookie) {
                 set req.http.Cookie = ";" + req.http.Cookie;
                 set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
-                set req.http.Cookie = regsuball(req.http.Cookie, ";(PHPSESSID)=", "; \1=");
+                set req.http.Cookie = regsuball(req.http.Cookie, ";(PHPSESSID|REMEMBERME)=", "; \1=");
                 set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
                 set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
 
diff --git a/http_client.rst b/http_client.rst
index bf64026b946..30379f9a3b3 100644
--- a/http_client.rst
+++ b/http_client.rst
@@ -1064,7 +1064,7 @@ To disable HTTP compression, send an ``Accept-Encoding: identity`` HTTP header.
 Chunked transfer encoding is enabled automatically if both your PHP runtime and
 the remote server support it.
 
-.. caution::
+.. warning::
 
     If you set ``Accept-Encoding`` to e.g. ``gzip``, you will need to handle the
     decompression yourself.
@@ -2332,15 +2332,15 @@ test it in a real application::
             $responseData = $service->createArticle($requestData);
 
             // Assert
-            self::assertSame('POST', $mockResponse->getRequestMethod());
-            self::assertSame('https://example.com/api/article', $mockResponse->getRequestUrl());
-            self::assertContains(
+            $this->assertSame('POST', $mockResponse->getRequestMethod());
+            $this->assertSame('https://example.com/api/article', $mockResponse->getRequestUrl());
+            $this->assertContains(
                 'Content-Type: application/json',
                 $mockResponse->getRequestOptions()['headers']
             );
-            self::assertSame($expectedRequestData, $mockResponse->getRequestOptions()['body']);
+            $this->assertSame($expectedRequestData, $mockResponse->getRequestOptions()['body']);
 
-            self::assertSame($responseData, $expectedResponseData);
+            $this->assertSame($expectedResponseData, $responseData);
         }
     }
 
@@ -2355,11 +2355,11 @@ First, use a browser or HTTP client to perform the HTTP request(s) you want to
 test. Then, save that information as a ``.har`` file somewhere in your application::
 
     // ExternalArticleServiceTest.php
-    use PHPUnit\Framework\TestCase;
+    use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
     use Symfony\Component\HttpClient\MockHttpClient;
     use Symfony\Component\HttpClient\Response\MockResponse;
 
-    final class ExternalArticleServiceTest extends TestCase
+    final class ExternalArticleServiceTest extends KernelTestCase
     {
         public function testSubmitData(): void
         {
@@ -2373,7 +2373,7 @@ test. Then, save that information as a ``.har`` file somewhere in your applicati
             $responseData = $service->createArticle($requestData);
 
             // Assert
-            self::assertSame($responseData, 'the expected response');
+            $this->assertSame('the expected response', $responseData);
         }
     }
 
diff --git a/lock.rst b/lock.rst
index d70f1d5535b..82ec48db572 100644
--- a/lock.rst
+++ b/lock.rst
@@ -189,7 +189,7 @@ To lock the default resource, autowire the lock factory using
         }
     }
 
-.. caution::
+.. warning::
 
     The same instance of ``LockInterface`` won't block when calling ``acquire``
     multiple times inside the same process. When several services use the
diff --git a/logging/channels_handlers.rst b/logging/channels_handlers.rst
index 9ad3a2f054c..3cac1d01ba5 100644
--- a/logging/channels_handlers.rst
+++ b/logging/channels_handlers.rst
@@ -95,7 +95,7 @@ from the ``security`` channel. The following example does that only in the
             }
         };
 
-.. caution::
+.. warning::
 
     The ``channels`` configuration only works for top-level handlers. Handlers
     that are nested inside a group, buffer, filter, fingers crossed or other
diff --git a/logging/monolog_exclude_http_codes.rst b/logging/monolog_exclude_http_codes.rst
index 810abdd5b9f..ee9fb16c01c 100644
--- a/logging/monolog_exclude_http_codes.rst
+++ b/logging/monolog_exclude_http_codes.rst
@@ -57,7 +57,7 @@ logging these HTTP codes based on the MonologBundle configuration:
             $mainHandler->excludedHttpCode()->code(404);
         };
 
-.. caution::
+.. warning::
 
     Combining ``excluded_http_codes`` with a ``passthru_level`` lower than
     ``error`` (i.e. ``debug``, ``info``, ``notice`` or ``warning``) will not
diff --git a/mailer.rst b/mailer.rst
index d2136839ad0..e5d646d5aa2 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -61,7 +61,7 @@ over SMTP by configuring the DSN in your ``.env`` file (the ``user``,
             $framework->mailer()->dsn(env('MAILER_DSN'));
         };
 
-.. caution::
+.. warning::
 
     If the username, password or host contain any character considered special in a
     URI (such as ``: / ? # [ ] @ ! $ & ' ( ) * + , ; =``), you must
@@ -82,7 +82,7 @@ native        ``native://default``                      Mailer uses the sendmail
                                                         ``php.ini`` settings when ``sendmail_path`` is not configured.
 ============  ========================================  ==============================================================
 
-.. caution::
+.. warning::
 
     When using ``native://default``, if ``php.ini`` uses the ``sendmail -t``
     command, you won't have error reporting and ``Bcc`` headers won't be removed.
@@ -100,6 +100,7 @@ via a third-party provider:
 ===================== =============================================== ===============
 Service               Install with                                    Webhook support
 ===================== =============================================== ===============
+`AhaSend`_            ``composer require symfony/aha-send-mailer``    yes
 `Amazon SES`_         ``composer require symfony/amazon-mailer``
 `Azure`_              ``composer require symfony/azure-mailer``
 `Brevo`_              ``composer require symfony/brevo-mailer``       yes
@@ -108,7 +109,7 @@ Service               Install with                                    Webhook su
 `Mailjet`_            ``composer require symfony/mailjet-mailer``     yes
 `Mailomat`_           ``composer require symfony/mailomat-mailer``    yes
 `MailPace`_           ``composer require symfony/mail-pace-mailer``
-`MailerSend`_         ``composer require symfony/mailer-send-mailer``
+`MailerSend`_         ``composer require symfony/mailer-send-mailer`` yes
 `Mailtrap`_           ``composer require symfony/mailtrap-mailer``    yes
 `Mandrill`_           ``composer require symfony/mailchimp-mailer``   yes
 `Postal`_             ``composer require symfony/postal-mailer``
@@ -127,6 +128,10 @@ Service               Install with                                    Webhook su
 
     The Mailomat, Mailtrap, Postal and Sweego integrations were introduced in Symfony 7.2.
 
+.. versionadded:: 7.3
+
+    The AhaSend integration was introduced in Symfony 7.3.
+
 .. note::
 
     As a convenience, Symfony also provides support for Gmail (``composer
@@ -175,6 +180,10 @@ party provider:
 +------------------------+---------------------------------------------------------+
 | Provider               | Formats                                                 |
 +========================+=========================================================+
+| `AhaSend`_             | - API ``ahasend+api://KEY@default``                     |
+|                        | - HTTP n/a                                              |
+|                        | - SMTP ``ahasend+smtp://USERNAME:PASSWORD@default``     |
++------------------------+---------------------------------------------------------+
 | `Amazon SES`_          | - SMTP ``ses+smtp://USERNAME:PASSWORD@default``         |
 |                        | - HTTP ``ses+https://ACCESS_KEY:SECRET_KEY@default``    |
 |                        | - API ``ses+api://ACCESS_KEY:SECRET_KEY@default``       |
@@ -246,20 +255,20 @@ party provider:
 |                        | - API ``sweego+api://API_KEY@default``                  |
 +------------------------+---------------------------------------------------------+
 
-.. caution::
+.. warning::
 
     If your credentials contain special characters, you must URL-encode them.
     For example, the DSN ``ses+smtp://ABC1234:abc+12/345@default`` should be
     configured as ``ses+smtp://ABC1234:abc%2B12%2F345@default``
 
-.. caution::
+.. warning::
 
     If you want to use the ``ses+smtp`` transport together with :doc:`Messenger </messenger>`
     to :ref:`send messages in background <mailer-sending-messages-async>`,
     you need to add the ``ping_threshold`` parameter to your ``MAILER_DSN`` with
     a value lower than ``10``: ``ses+smtp://USERNAME:PASSWORD@default?ping_threshold=9``
 
-.. caution::
+.. warning::
 
     If you send custom headers when using the `Amazon SES`_ transport (to receive
     them later via a webhook), make sure to use the ``ses+https`` provider because
@@ -331,6 +340,17 @@ The failover-transport starts using the first transport and if it fails, it
 will retry the same delivery with the next transports until one of them succeeds
 (or until all of them fail).
 
+By default, delivery is retried 60 seconds after a failed attempt. You can adjust
+the retry period by setting the ``retry_period`` option in the DSN:
+
+.. code-block:: env
+
+    MAILER_DSN="failover(postmark+api://ID@default sendgrid+smtp://KEY@default)?retry_period=15"
+
+.. versionadded:: 7.3
+
+    The ``retry_period`` option was introduced in Symfony 7.3.
+
 Load Balancing
 ~~~~~~~~~~~~~~
 
@@ -351,6 +371,17 @@ As with the failover transport, round-robin retries deliveries until
 a transport succeeds (or all fail). In contrast to the failover transport,
 it *spreads* the load across all its transports.
 
+By default, delivery is retried 60 seconds after a failed attempt. You can adjust
+the retry period by setting the ``retry_period`` option in the DSN:
+
+.. code-block:: env
+
+    MAILER_DSN="roundrobin(postmark+api://ID@default sendgrid+smtp://KEY@default)?retry_period=15"
+
+.. versionadded:: 7.3
+
+    The ``retry_period`` option was introduced in Symfony 7.3.
+
 TLS Peer Verification
 ~~~~~~~~~~~~~~~~~~~~~
 
@@ -385,7 +416,7 @@ setting the ``auto_tls`` option to ``false`` in the DSN::
 
     $dsn = 'smtp://user:pass@10.0.0.25?auto_tls=false';
 
-.. caution::
+.. warning::
 
     It's not recommended to disable TLS while connecting to an SMTP server over
     the Internet, but it can be useful when both the application and the SMTP
@@ -560,17 +591,17 @@ both strings or address objects::
         // ...
     ;
 
-.. versionadded:: 7.2
-
-    Support for non-ASCII email addresses (e.g. ``jânë.dœ@ëxãmplę.com``)
-    was introduced in Symfony 7.2.
-
 .. tip::
 
     Instead of calling ``->from()`` *every* time you create a new email, you can
     :ref:`configure emails globally <mailer-configure-email-globally>` to set the
     same ``From`` email to all messages.
 
+.. versionadded:: 7.2
+
+    Support for non-ASCII email addresses (e.g. ``jânë.dœ@ëxãmplę.com``)
+    was introduced in Symfony 7.2.
+
 .. note::
 
     The local part of the address (what goes before the ``@``) can include UTF-8
@@ -795,7 +826,7 @@ and headers.
             $mailer->header('X-Custom-Header')->value('foobar');
         };
 
-.. caution::
+.. warning::
 
     Some third-party providers don't support the usage of keywords like ``from``
     in the ``headers``. Check out your provider's documentation before setting
@@ -1218,7 +1249,7 @@ Before signing/encrypting messages, make sure to have:
     When using OpenSSL to generate certificates, make sure to add the
     ``-addtrust emailProtection`` command option.
 
-.. caution::
+.. warning::
 
     Signing and encrypting messages require their contents to be fully rendered.
     For example, the content of :ref:`templated emails <mailer-twig>` is rendered
@@ -1243,7 +1274,7 @@ using for example OpenSSL or obtained at an official Certificate Authority (CA).
 The email recipient must have the CA certificate in the list of trusted issuers
 in order to verify the signature.
 
-.. caution::
+.. warning::
 
     If you use message signature, sending to ``Bcc`` will be removed from the
     message. If you need to send a message to multiple recipients, you need
@@ -1991,6 +2022,7 @@ the :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\MailerAssertionsTrait`::
    following the redirection and the message will be lost from the mailer event
    handler.
 
+.. _`AhaSend`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/AhaSend/README.md
 .. _`Amazon SES`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Amazon/README.md
 .. _`Azure`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Mailer/Bridge/Azure/README.md
 .. _`App Password`: https://support.google.com/accounts/answer/185833
diff --git a/mercure.rst b/mercure.rst
index f80e3fa4bad..f37c40ddee7 100644
--- a/mercure.rst
+++ b/mercure.rst
@@ -48,13 +48,28 @@ Run this command to install the Mercure support:
 
     $ composer require mercure
 
+Running a Mercure Hub
+~~~~~~~~~~~~~~~~~~~~~
+
 To manage persistent connections, Mercure relies on a Hub: a dedicated server
 that handles persistent SSE connections with the clients.
 The Symfony app publishes the updates to the hub, that will broadcast them to
 clients.
 
+.. raw:: html
+
+    <object data="_images/mercure/hub.svg" type="image/svg+xml"
+        alt="Flow diagram showing a Symfony app communicating with the Mercure Hub using a POST request, and the Mercure Hub using SSE to communicate to the clients."
+    ></object>
+
+In production, you have to install a Mercure hub by yourself.
+An official and open source (AGPL) hub based on the Caddy web server
+can be downloaded as a static binary from `Mercure.rocks`_.
+A Docker image, a Helm chart for Kubernetes
+and a managed, High Availability Hub are also provided.
+
 Thanks to :doc:`the Docker integration of Symfony </setup/docker>`,
-:ref:`Flex <symfony-flex>` proposes to install a Mercure hub.
+:ref:`Flex <symfony-flex>` proposes to install a Mercure hub for development.
 Run ``docker-compose up`` to start the hub if you have chosen this option.
 
 If you use the :doc:`Symfony Local Web Server </setup/symfony_server>`,
@@ -64,23 +79,7 @@ you must start it with the ``--no-tls`` option.
 
     $ symfony server:start --no-tls -d
 
-Running a Mercure Hub
-~~~~~~~~~~~~~~~~~~~~~
-
-.. raw:: html
-
-    <object data="_images/mercure/hub.svg" type="image/svg+xml"
-        alt="Flow diagram showing a Symfony app communicating with the Mercure Hub using a POST request, and the Mercure Hub using SSE to communicate to the clients."
-    ></object>
-
-If you use the Docker integration, a hub is already up and running,
-and you can go straight to the next section.
-
-Otherwise, and in production, you have to install a hub by yourself.
-An official and open source (AGPL) Hub based on the Caddy web server
-can be downloaded as a static binary from `Mercure.rocks`_.
-A Docker image, a Helm chart for Kubernetes
-and a managed, High Availability Hub are also provided.
+If you use the Docker integration, a hub is already up and running.
 
 Configuration
 -------------
@@ -131,11 +130,12 @@ MercureBundle provides a more advanced configuration:
         mercure:
             hubs:
                 default:
-                    url: https://mercure-hub.example.com/.well-known/mercure
+                    url: '%env(string:MERCURE_URL)%'
+                    public_url: '%env(string:MERCURE_PUBLIC_URL)%'
                     jwt:
-                        secret: '!ChangeThisMercureHubJWTSecretKey!'
-                        publish: ['foo', 'https://example.com/foo']
-                        subscribe: ['bar', 'https://example.com/bar']
+                        secret: '%env(string:MERCURE_JWT_SECRET)%'
+                        publish: ['https://example.com/foo1', 'https://example.com/foo2']
+                        subscribe: ['https://example.com/bar1', 'https://example.com/bar2']
                         algorithm: 'hmac.sha256'
                         provider: 'My\Provider'
                         factory: 'My\Factory'
@@ -148,19 +148,20 @@ MercureBundle provides a more advanced configuration:
         <config>
             <hub
                 name="default"
-                url="https://mercure-hub.example.com/.well-known/mercure"
-            >
+                url="%env(string:MERCURE_URL)%"
+                public_url="%env(string:MERCURE_PUBLIC_URL)%"
+            > <!-- public_url defaults to url -->
                 <jwt
-                    secret="!ChangeThisMercureHubJWTSecretKey!"
+                    secret="%env(string:MERCURE_JWT_SECRET)%"
                     algorithm="hmac.sha256"
                     provider="My\Provider"
                     factory="My\Factory"
                     value="my.jwt"
                 >
-                    <publish>foo</publish>
-                    <publish>https://example.com/foo</publish>
-                    <subscribe>bar</subscribe>
-                    <subscribe>https://example.com/bar</subscribe>
+                    <publish>https://example.com/foo1</publish>
+                    <publish>https://example.com/foo2</publish>
+                    <subscribe>https://example.com/bar1</subscribe>
+                    <subscribe>https://example.com/bar2</subscribe>
                 </jwt>
             </hub>
         </config>
@@ -171,11 +172,12 @@ MercureBundle provides a more advanced configuration:
         $container->loadFromExtension('mercure', [
             'hubs' => [
                 'default' => [
-                    'url' => 'https://mercure-hub.example.com/.well-known/mercure',
+                    'url' => '%env(string:MERCURE_URL)%',
+                    'public_url' => '%env(string:MERCURE_PUBLIC_URL)%',
                     'jwt' => [
-                        'secret' => '!ChangeThisMercureHubJWTSecretKey!',
-                        'publish' => ['foo', 'https://example.com/foo'],
-                        'subscribe' => ['bar', 'https://example.com/bar'],
+                        'secret' => '%env(string:MERCURE_JWT_SECRET)%',
+                        'publish' => ['https://example.com/foo1', 'https://example.com/foo2'],
+                        'subscribe' => ['https://example.com/bar1', 'https://example.com/bar2'],
                         'algorithm' => 'hmac.sha256',
                         'provider' => 'My\Provider',
                         'factory' => 'My\Factory',
@@ -309,22 +311,16 @@ as patterns:
 
 .. tip::
 
-    Google Chrome DevTools natively integrate a `practical UI`_ displaying in live
-    the received events:
+    Test if a URI Template matches a URL using `the online debugger`_
 
-    .. image:: /_images/mercure/chrome.png
-        :alt: The Chrome DevTools showing the EventStream tab containing information about each SSE event.
-
-    To use it:
+.. tip::
 
-    * open the DevTools
-    * select the "Network" tab
-    * click on the request to the Mercure hub
-    * click on the "EventStream" sub-tab.
+    Google Chrome features a practical UI to display the received events:
 
-.. tip::
+    .. image:: /_images/mercure/chrome.png
+        :alt: The Chrome DevTools showing the EventStream tab containing information about each SSE event.
 
-    Test if a URI Template match a URL using `the online debugger`_
+    In DevTools, select the "Network" tab, then click on the request to the Mercure hub, then on the "EventStream" sub-tab.
 
 Discovery
 ---------
@@ -446,7 +442,7 @@ Using cookies is the most secure and preferred way when the client is a web
 browser. If the client is not a web browser, then using an authorization header
 is the way to go.
 
-.. caution::
+.. warning::
 
     To use the cookie authentication method, the Symfony app and the Hub
     must be served from the same domain (can be different sub-domains).
@@ -677,7 +673,7 @@ sent:
         mercure.hub.default:
             class: App\Tests\Functional\Stub\HubStub
 
-As MercureBundle support multiple hubs, you may have to replace
+As MercureBundle supports multiple hubs, you may have to replace
 the other service definitions accordingly.
 
 .. tip::
@@ -691,8 +687,6 @@ Debugging
 
     The WebProfiler panel was introduced in MercureBundle 0.2.
 
-Enable the panel in your configuration, as follows:
-
 MercureBundle is shipped with a debug panel. Install the Debug pack to
 enable it::
 
@@ -767,7 +761,6 @@ Going further
 .. _`JSON Web Token`: https://tools.ietf.org/html/rfc7519
 .. _`example JWT`: https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdfX0.iHLdpAEjX4BqCsHJEegxRmO-Y6sMxXwNATrQyRNt3GY
 .. _`IRI`: https://tools.ietf.org/html/rfc3987
-.. _`practical UI`: https://twitter.com/ChromeDevTools/status/562324683194785792
 .. _`the dedicated API Platform documentation`: https://api-platform.com/docs/core/mercure/
 .. _`the online debugger`: https://uri-template-tester.mercure.rocks
 .. _`a feature to test applications using Mercure`: https://github.com/symfony/panther#creating-isolated-browsers-to-test-apps-using-mercure-or-websocket
diff --git a/messenger.rst b/messenger.rst
index 74f7d792436..0965cbc9170 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -783,7 +783,7 @@ times:
 Change the ``async`` argument to use the name of your transport (or transports)
 and ``user`` to the Unix user on your server.
 
-.. caution::
+.. warning::
 
     During a deployment, something might be unavailable (e.g. the
     database) causing the consumer to fail to start. In this situation,
@@ -958,7 +958,7 @@ Rate Limited Transport
 ~~~~~~~~~~~~~~~~~~~~~~
 
 Sometimes you might need to rate limit your message worker. You can configure a
-rate limiter on a transport (requires the :doc:`RateLimiter component </rate-limiter>`)
+rate limiter on a transport (requires the :doc:`RateLimiter component </rate_limiter>`)
 by setting its ``rate_limiter`` option:
 
 .. configuration-block::
@@ -1005,7 +1005,7 @@ by setting its ``rate_limiter`` option:
             ;
         };
 
-.. caution::
+.. warning::
 
     When a rate limiter is configured on a transport, it will block the whole
     worker when the limit is hit. You should make sure you configure a dedicated
@@ -1134,6 +1134,15 @@ and must be retried. If you throw
 :class:`Symfony\\Component\\Messenger\\Exception\\RecoverableMessageHandlingException`,
 the message will always be retried infinitely and ``max_retries`` setting will be ignored.
 
+You can define a custom retry delay (e.g., to use the value from the ``Retry-After``
+header in an HTTP response) by setting the ``retryDelay`` argument in the
+constructor of the ``RecoverableMessageHandlingException``.
+
+.. versionadded:: 7.2
+
+    The ``retryDelay`` argument and the ``getRetryDelay()`` method were introduced
+    in Symfony 7.2.
+
 .. _messenger-failure-transport:
 
 Saving & Retrying Failed Messages
@@ -1513,7 +1522,7 @@ The transport has a number of options:
     (no description available)
 
 ``sasl_method``
-
+    (no description available)
 
 ``connection_name``
     For custom connection names (requires at least version 1.10 of the PHP AMQP
@@ -1576,7 +1585,7 @@ your Envelope::
         new AmqpStamp('custom-routing-key', AMQP_NOPARAM, $attributes),
     ]);
 
-.. caution::
+.. warning::
 
     The consumers do not show up in an admin panel as this transport does not rely on
     ``\AmqpQueue::consume()`` which is blocking. Having a blocking receiver makes
@@ -1627,12 +1636,6 @@ DSN by using the ``table_name`` option:
 Or, to create the table yourself, set the ``auto_setup`` option to ``false`` and
 :ref:`generate a migration <doctrine-creating-the-database-tables-schema>`.
 
-.. caution::
-
-    The datetime property of the messages stored in the database uses the
-    timezone of the current system. This may cause issues if multiple machines
-    with different timezone configuration use the same storage.
-
 The transport has a number of options:
 
 ``table_name`` (default: ``messenger_messages``)
@@ -1821,7 +1824,7 @@ under the transport in ``messenger.yaml``:
                                 verify_peer: true
                                 verify_peer_name: true
 
-.. caution::
+.. warning::
 
     There should never be more than one ``messenger:consume`` command running with the same
     combination of ``stream``, ``group`` and ``consumer``, or messages could end up being
@@ -2687,7 +2690,7 @@ That's it! You can now consume each transport:
 
     $ php bin/console messenger:consume async_priority_normal -vv
 
-.. caution::
+.. warning::
 
     If a handler does *not* have ``from_transport`` config, it will be executed
     on *every* transport that the message is received from.
diff --git a/notifier.rst b/notifier.rst
index 144044ebe3e..090f4db2007 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -33,8 +33,14 @@ The notifier component supports the following channels:
   services like Slack and Telegram;
 * :ref:`Email channel <notifier-email-channel>` integrates the :doc:`Symfony Mailer </mailer>`;
 * Browser channel uses :ref:`flash messages <flash-messages>`.
-* :ref:`Push channel <notifier-push-channel>` sends notifications to phones and browsers via push notifications.
-* :ref:`Desktop channel <notifier-desktop-channel>` displays desktop notifications on the same host machine.
+* :ref:`Push channel <notifier-push-channel>` sends notifications to phones and
+  browsers via push notifications.
+* :ref:`Desktop channel <notifier-desktop-channel>` displays desktop notifications
+  on the same host machine.
+
+.. versionadded:: 7.2
+
+    The ``Desktop`` channel was introduced in Symfony 7.2.
 
 .. _notifier-sms-channel:
 
@@ -46,7 +52,7 @@ to send SMS messages to mobile phones. This feature requires subscribing to
 a third-party service that sends SMS messages. Symfony provides integration
 with a couple popular SMS services:
 
-.. caution::
+.. warning::
 
     If any of the DSN values contains any character considered special in a
     URI (such as ``: / ? # [ ] @ ! $ & ' ( ) * + , ; =``), you must
@@ -70,7 +76,7 @@ Service
                     **Webhook support**: No
 `Brevo`_            **Install**: ``composer require symfony/brevo-notifier`` \
                     **DSN**: ``brevo://API_KEY@default?sender=SENDER`` \
-                    **Webhook support**: No
+                    **Webhook support**: Yes
 `Clickatell`_       **Install**: ``composer require symfony/clickatell-notifier`` \
                     **DSN**: ``clickatell://ACCESS_TOKEN@default?from=FROM`` \
                     **Webhook support**: No
@@ -230,6 +236,10 @@ Service
 
     The ``Primotexto``, ``Sipgate`` and ``Sweego`` integrations were introduced in Symfony 7.2.
 
+.. versionadded:: 7.3
+
+    Webhook support for the ``Brevo`` integration was introduced in Symfony 7.3.
+
 .. deprecated:: 7.1
 
     The `Sms77`_ integration is deprecated since
@@ -333,7 +343,7 @@ information such as the message ID and the original message contents.
 Chat Channel
 ~~~~~~~~~~~~
 
-.. caution::
+.. warning::
 
     If any of the DSN values contains any character considered special in a
     URI (such as ``: / ? # [ ] @ ! $ & ' ( ) * + , ; =``), you must
@@ -382,7 +392,7 @@ Service                                  Package                               D
     The ``Gitter`` integration was removed in Symfony 7.2 because that service
     no longer provides an API.
 
-.. caution::
+.. warning::
 
     By default, if you have the :doc:`Messenger component </messenger>` installed,
     the notifications will be sent through the MessageBus. If you don't have a
@@ -552,7 +562,7 @@ notification emails:
 Push Channel
 ~~~~~~~~~~~~
 
-.. caution::
+.. warning::
 
     If any of the DSN values contains any character considered special in a
     URI (such as ``: / ? # [ ] @ ! $ & ' ( ) * + , ; =``), you must
@@ -635,9 +645,9 @@ configure the ``texter_transports``:
 Desktop Channel
 ~~~~~~~~~~~~~~~
 
-The desktop channel is used to display desktop notifications on the same host machine using
-:class:`Symfony\\Component\\Notifier\\Texter` classes. Currently, Symfony
-is integrated with the following providers:
+The desktop channel is used to display local desktop notifications on the same
+host machine using :class:`Symfony\\Component\\Notifier\\Texter` classes. Currently,
+Symfony is integrated with the following providers:
 
 ===============  ====================================  ==============================================================================
 Provider         Package                               DSN
@@ -645,18 +655,23 @@ Provider         Package                               DSN
 `JoliNotif`_     ``symfony/joli-notif-notifier``       ``jolinotif://default``
 ===============  ====================================  ==============================================================================
 
-.. versionadded: 7.2
+.. versionadded:: 7.2
 
     The JoliNotif bridge was introduced in Symfony 7.2.
 
-To enable a texter, add the correct DSN in your ``.env`` file and
-configure the ``texter_transports``:
+If you are using :ref:`Symfony Flex <symfony-flex>`, installing that package will
+also create the necessary environment variable and configuration. Otherwise, you'll
+need to add the following manually:
+
+1) Add the correct DSN in your ``.env`` file:
 
 .. code-block:: bash
 
     # .env
     JOLINOTIF=jolinotif://default
 
+2) Update the Notifier configuration to add a new texter transport:
+
 .. configuration-block::
 
     .. code-block:: yaml
@@ -699,9 +714,49 @@ configure the ``texter_transports``:
             ;
         };
 
-.. versionadded:: 7.2
+Now you can send notifications to your desktop as follows::
 
-    The ``Desktop`` channel was introduced in Symfony 7.2.
+    // src/Notifier/SomeService.php
+    use Symfony\Component\Notifier\Message\DesktopMessage;
+    use Symfony\Component\Notifier\TexterInterface;
+    // ...
+
+    class SomeService
+    {
+        public function __construct(
+            private TexterInterface $texter,
+        ) {
+        }
+
+        public function notifyNewSubscriber(User $user): void
+        {
+            $message = new DesktopMessage(
+                'New subscription! 🎉',
+                sprintf('%s is a new subscriber', $user->getFullName())
+            );
+
+            $texter->send($message);
+        }
+    }
+
+These notifications can be customized further, and depending on your operating system,
+they may support features like custom sounds, icons, and more::
+
+    use Symfony\Component\Notifier\Bridge\JoliNotif\JoliNotifOptions;
+    // ...
+
+    $options = (new JoliNotifOptions())
+        ->setIconPath('/path/to/icons/error.png')
+        ->setExtraOption('sound', 'sosumi')
+        ->setExtraOption('url', 'https://example.com');
+
+    $message = new DesktopMessage('Production is down', <<<CONTENT
+        ❌ Server prod-1 down
+        ❌ Server prod-2 down
+        ✅ Network is up
+        CONTENT, $options);
+
+    $texter->send($message);
 
 Configure to use Failover or Round-Robin Transports
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/profiler.rst b/profiler.rst
index 717094bff31..57d412472ba 100644
--- a/profiler.rst
+++ b/profiler.rst
@@ -303,13 +303,13 @@ These are the method that you can define in the data collector class:
     from ``AbstractDataCollector``). If you need some services to collect the
     data, inject those services in the data collector constructor.
 
-    .. caution::
+    .. warning::
 
         The ``collect()`` method is only called once. It is not used to "gather"
         data but is there to "pick up" the data that has been stored by your
         service.
 
-    .. caution::
+    .. warning::
 
         As the profiler serializes data collector instances, you should not
         store objects that cannot be serialized (like PDO objects) or you need
diff --git a/reference/attributes.rst b/reference/attributes.rst
index 19a27b71793..a8399dafe28 100644
--- a/reference/attributes.rst
+++ b/reference/attributes.rst
@@ -33,7 +33,7 @@ Dependency Injection
 * :ref:`Autowire <autowire-attribute>`
 * :ref:`AutowireCallable <autowiring_closures>`
 * :doc:`AutowireDecorated </service_container/service_decoration>`
-* :doc:`AutowireIterator <service-locator_autowire-iterator>`
+* :ref:`AutowireIterator <service-locator_autowire-iterator>`
 * :ref:`AutowireLocator <service-locator_autowire-locator>`
 * :ref:`AutowireMethodOf <autowiring_closures>`
 * :ref:`AutowireServiceClosure <autowiring_closures>`
@@ -106,16 +106,18 @@ Security
 * :ref:`IsCsrfTokenValid <csrf-controller-attributes>`
 * :ref:`IsGranted <security-securing-controller-attributes>`
 
+.. _reference-attributes-serializer:
+
 Serializer
 ~~~~~~~~~~
 
-* :ref:`Context <serializer_serializer-context>`
+* :ref:`Context <serializer-context>`
 * :ref:`DiscriminatorMap <serializer_interfaces-and-abstract-classes>`
-* :ref:`Groups <component-serializer-attributes-groups-attributes>`
+* :ref:`Groups <serializer-groups-attribute>`
 * :ref:`Ignore <serializer_ignoring-attributes>`
 * :ref:`MaxDepth <serializer_handling-serialization-depth>`
-* :ref:`SerializedName <serializer_name-conversion>`
-* :ref:`SerializedPath <serializer-enabling-metadata-cache>`
+* :ref:`SerializedName <serializer-name-conversion>`
+* :ref:`SerializedPath <serializer-nested-structures>`
 
 Twig
 ~~~~
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 53edf220642..4ce41c3615d 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -175,7 +175,7 @@ named ``kernel.http_method_override``.
     :ref:`Changing the Action and HTTP Method <forms-change-action-method>` of
     Symfony forms.
 
-.. caution::
+.. warning::
 
     If you're using the :ref:`HttpCache Reverse Proxy <symfony2-reverse-proxy>`
     with this option, the kernel will ignore the ``_method`` parameter,
@@ -193,8 +193,6 @@ named ``kernel.http_method_override``.
         $request = Request::createFromGlobals();
         // ...
 
-.. _configuration-framework-http_method_override:
-
 trust_x_sendfile_type_header
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -2941,11 +2939,11 @@ enable_attributes
 
 **type**: ``boolean`` **default**: ``true``
 
-If this option is enabled, serialization groups can be defined using `PHP attributes`_.
+Enables support for `PHP attributes`_ in the serializer component.
 
 .. seealso::
 
-    For more information, see :ref:`serializer-using-serialization-groups-attributes`.
+    See :ref:`the reference <reference-attributes-serializer>` for a list of supported annotations.
 
 .. _reference-serializer-name_converter:
 
@@ -2961,8 +2959,7 @@ value.
 
 .. seealso::
 
-    For more information, see
-    :ref:`component-serializer-converting-property-names-when-serializing-and-deserializing`.
+    For more information, see :ref:`serializer-name-conversion`.
 
 .. _reference-serializer-circular_reference_handler:
 
diff --git a/reference/configuration/web_profiler.rst b/reference/configuration/web_profiler.rst
index f0b11f47064..93c65621999 100644
--- a/reference/configuration/web_profiler.rst
+++ b/reference/configuration/web_profiler.rst
@@ -20,7 +20,7 @@ under the ``web_profiler`` key in your application configuration.
     namespace and the related XSD schema is available at:
     ``https://symfony.com/schema/dic/webprofiler/webprofiler-1.0.xsd``
 
-.. caution::
+.. warning::
 
     The web debug toolbar is not available for responses of type ``StreamedResponse``.
 
diff --git a/reference/constraints/Bic.rst b/reference/constraints/Bic.rst
index 3f05e5eac25..6cde4a11bac 100644
--- a/reference/constraints/Bic.rst
+++ b/reference/constraints/Bic.rst
@@ -124,18 +124,13 @@ Parameter        Description
 ``mode``
 ~~~~~~~~
 
-**type**: ``string`` **default**: ``strict``
+**type**: ``string`` **default**: ``Bic::VALIDATION_MODE_STRICT``
 
-This option defines how the BIC is validated:
+This option defines how the BIC is validated. The possible values are available
+as constants in the :class:`Symfony\\Component\\Validator\\Constraints\\Bic` class:
 
-* ``strict`` validates the given value without any modification;
-* ``case-insensitive`` converts the given value to uppercase before validating it.
-
-.. tip::
-
-    The possible values of this option are also defined as PHP constants of
-    :class:`Symfony\\Component\\Validator\\Constraints\\BIC`
-    (e.g. ``BIC::VALIDATION_MODE_CASE_INSENSITIVE``).
+* ``Bic::VALIDATION_MODE_STRICT`` validates the given value without any modification;
+* ``Bic::VALIDATION_MODE_CASE_INSENSITIVE`` converts the given value to uppercase before validating it.
 
 .. versionadded:: 7.2
 
diff --git a/reference/constraints/Callback.rst b/reference/constraints/Callback.rst
index 3424d47c9d3..f4c78a9642a 100644
--- a/reference/constraints/Callback.rst
+++ b/reference/constraints/Callback.rst
@@ -245,7 +245,7 @@ constructor of the Callback constraint::
         }
     }
 
-.. caution::
+.. warning::
 
     Using a ``Closure`` together with attribute configuration will disable the
     attribute cache for that class/property/method because ``Closure`` cannot
@@ -271,14 +271,16 @@ callback method:
 * A closure.
 
 Concrete callbacks receive an :class:`Symfony\\Component\\Validator\\Context\\ExecutionContextInterface`
-instance as the first argument and the :ref:`payload option <reference-constraints-payload>`
+instance as the first argument and the :ref:`payload option <reference-constraints-callback-payload>`
 as the second argument.
 
 Static or closure callbacks receive the validated object as the first argument,
 the :class:`Symfony\\Component\\Validator\\Context\\ExecutionContextInterface`
-instance as the second argument and the :ref:`payload option <reference-constraints-payload>`
+instance as the second argument and the :ref:`payload option <reference-constraints-callback-payload>`
 as the third argument.
 
 .. include:: /reference/constraints/_groups-option.rst.inc
 
+.. _reference-constraints-callback-payload:
+
 .. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/DateTime.rst b/reference/constraints/DateTime.rst
index f6bcce7e5f5..ffcfbf55dda 100644
--- a/reference/constraints/DateTime.rst
+++ b/reference/constraints/DateTime.rst
@@ -99,11 +99,16 @@ This message is shown if the underlying data is not a valid datetime.
 
 You can use the following parameters in this message:
 
-===============  ==============================================================
-Parameter        Description
-===============  ==============================================================
-``{{ value }}``  The current (invalid) value
-``{{ label }}``  Corresponding form field label
-===============  ==============================================================
+================  ==============================================================
+Parameter         Description
+================  ==============================================================
+``{{ value }}``   The current (invalid) value
+``{{ label }}``   Corresponding form field label
+``{{ format }}``  The date format defined in ``format``
+================  ==============================================================
+
+.. versionadded:: 7.3
+
+    The ``{{ format }}`` parameter was introduced in Symfony 7.3.
 
 .. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/EqualTo.rst b/reference/constraints/EqualTo.rst
index d2f151adea8..d5d78f60a0f 100644
--- a/reference/constraints/EqualTo.rst
+++ b/reference/constraints/EqualTo.rst
@@ -4,7 +4,7 @@ EqualTo
 Validates that a value is equal to another value, defined in the options.
 To force that a value is *not* equal, see :doc:`/reference/constraints/NotEqualTo`.
 
-.. caution::
+.. warning::
 
     This constraint compares using ``==``, so ``3`` and ``"3"`` are considered
     equal. Use :doc:`/reference/constraints/IdenticalTo` to compare with
diff --git a/reference/constraints/File.rst b/reference/constraints/File.rst
index 205d78b5cbb..6d9b72d17b8 100644
--- a/reference/constraints/File.rst
+++ b/reference/constraints/File.rst
@@ -242,7 +242,7 @@ Parameter         Description
 
 **type**: ``array`` or ``string``
 
-.. caution::
+.. warning::
 
     You should always use the ``extensions`` option instead of ``mimeTypes``
     except if you explicitly don't want to check that the extension of the file
@@ -298,7 +298,12 @@ Parameter                       Description
 The message displayed if the extension of the file is not a valid extension
 per the `extensions`_ option.
 
-.. include:: /reference/constraints/_parameters-mime-types-message-option.rst.inc
+====================  ==============================================================
+Parameter             Description
+====================  ==============================================================
+``{{ extension }}``   The extension of the given file
+``{{ extensions }}``  The list of allowed file extensions
+====================  ==============================================================
 
 ``mimeTypesMessage``
 ~~~~~~~~~~~~~~~~~~~~
diff --git a/reference/constraints/IdenticalTo.rst b/reference/constraints/IdenticalTo.rst
index 507493b63d4..5b6d853dc0b 100644
--- a/reference/constraints/IdenticalTo.rst
+++ b/reference/constraints/IdenticalTo.rst
@@ -5,7 +5,7 @@ Validates that a value is identical to another value, defined in the options.
 To force that a value is *not* identical, see
 :doc:`/reference/constraints/NotIdenticalTo`.
 
-.. caution::
+.. warning::
 
     This constraint compares using ``===``, so ``3`` and ``"3"`` are *not*
     considered equal. Use :doc:`/reference/constraints/EqualTo` to compare
diff --git a/reference/constraints/Image.rst b/reference/constraints/Image.rst
index 48dc1d5e0ed..23fbe5a157a 100644
--- a/reference/constraints/Image.rst
+++ b/reference/constraints/Image.rst
@@ -210,6 +210,10 @@ add several other options.
 
 If this option is false, the image cannot be landscape oriented.
 
+.. versionadded:: 7.3
+
+    The ``allowLandscape`` option support for SVG files was introduced in Symfony 7.3.
+
 ``allowLandscapeMessage``
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -234,6 +238,10 @@ Parameter         Description
 
 If this option is false, the image cannot be portrait oriented.
 
+.. versionadded:: 7.3
+
+    The ``allowPortrait`` option support for SVG files was introduced in Symfony 7.3.
+
 ``allowPortraitMessage``
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -260,6 +268,10 @@ If this option is false, the image cannot be a square. If you want to force
 a square image, then leave this option as its default ``true`` value
 and set `allowLandscape`_ and `allowPortrait`_ both to ``false``.
 
+.. versionadded:: 7.3
+
+    The ``allowSquare`` option support for SVG files was introduced in Symfony 7.3.
+
 ``allowSquareMessage``
 ~~~~~~~~~~~~~~~~~~~~~~
 
@@ -358,6 +370,10 @@ Parameter             Description
 If set, the aspect ratio (``width / height``) of the image file must be less
 than or equal to this value.
 
+.. versionadded:: 7.3
+
+    The ``maxRatio`` option support for SVG files was introduced in Symfony 7.3.
+
 ``maxRatioMessage``
 ~~~~~~~~~~~~~~~~~~~
 
@@ -477,6 +493,10 @@ Parameter             Description
 If set, the aspect ratio (``width / height``) of the image file must be greater
 than or equal to this value.
 
+.. versionadded:: 7.3
+
+    The ``minRatio`` option support for SVG files was introduced in Symfony 7.3.
+
 ``minRatioMessage``
 ~~~~~~~~~~~~~~~~~~~
 
diff --git a/reference/constraints/MacAddress.rst b/reference/constraints/MacAddress.rst
index 59adffe7c11..9a282ddf118 100644
--- a/reference/constraints/MacAddress.rst
+++ b/reference/constraints/MacAddress.rst
@@ -132,6 +132,7 @@ Parameter                         Allowed MAC addresses
 ``multicast_no_broadcast``        Only multicast except broadcast
 ``unicast_all``                   Only unicast
 ``universal_all``                 Only universal
+``universal_unicast``             Only universal and unicast
 ``universal_multicast``           Only universal and multicast
 ================================  =========================================
 
diff --git a/reference/constraints/NotEqualTo.rst b/reference/constraints/NotEqualTo.rst
index 37b03c35907..b8ee4cac32f 100644
--- a/reference/constraints/NotEqualTo.rst
+++ b/reference/constraints/NotEqualTo.rst
@@ -5,7 +5,7 @@ Validates that a value is **not** equal to another value, defined in the
 options. To force that a value is equal, see
 :doc:`/reference/constraints/EqualTo`.
 
-.. caution::
+.. warning::
 
     This constraint compares using ``!=``, so ``3`` and ``"3"`` are considered
     equal. Use :doc:`/reference/constraints/NotIdenticalTo` to compare with
diff --git a/reference/constraints/NotIdenticalTo.rst b/reference/constraints/NotIdenticalTo.rst
index ba28fdb7c45..9ea93dc4b86 100644
--- a/reference/constraints/NotIdenticalTo.rst
+++ b/reference/constraints/NotIdenticalTo.rst
@@ -5,7 +5,7 @@ Validates that a value is **not** identical to another value, defined in
 the options. To force that a value is identical, see
 :doc:`/reference/constraints/IdenticalTo`.
 
-.. caution::
+.. warning::
 
     This constraint compares using ``!==``, so ``3`` and ``"3"`` are
     considered not equal. Use :doc:`/reference/constraints/NotEqualTo` to
diff --git a/reference/constraints/PasswordStrength.rst b/reference/constraints/PasswordStrength.rst
index 671b5f495ef..60125a763a1 100644
--- a/reference/constraints/PasswordStrength.rst
+++ b/reference/constraints/PasswordStrength.rst
@@ -178,7 +178,7 @@ service to use your own estimator:
                 class: App\Validator\CustomPasswordStrengthEstimator
 
             Symfony\Component\Validator\Constraints\PasswordStrengthValidator:
-                arguments: [!service_closure '@custom_password_strength_estimator']
+                arguments: [!closure '@custom_password_strength_estimator']
 
     .. code-block:: xml
 
@@ -192,7 +192,7 @@ service to use your own estimator:
                 <service id="custom_password_strength_estimator" class="App\Validator\CustomPasswordStrengthEstimator"/>
 
                 <service id="Symfony\Component\Validator\Constraints\PasswordStrengthValidator">
-                    <argument type="service_closure" id="custom_password_strength_estimator"/>
+                    <argument type="closure" id="custom_password_strength_estimator"/>
                 </service>
             </services>
         </container>
@@ -210,5 +210,5 @@ service to use your own estimator:
             $services->set('custom_password_strength_estimator', CustomPasswordStrengthEstimator::class);
 
             $services->set(PasswordStrengthValidator::class)
-                ->args([service_closure('custom_password_strength_estimator')]);
+                ->args([closure('custom_password_strength_estimator')]);
         };
diff --git a/reference/constraints/Slug.rst b/reference/constraints/Slug.rst
new file mode 100644
index 00000000000..2eb82cd9c10
--- /dev/null
+++ b/reference/constraints/Slug.rst
@@ -0,0 +1,119 @@
+Slug
+====
+
+.. versionadded:: 7.3
+
+    The ``Slug`` constraint was introduced in Symfony 7.3.
+
+Validates that a value is a slug. By default, a slug is a string that matches
+the following regular expression: ``/^[a-z0-9]+(?:-[a-z0-9]+)*$/``.
+
+.. include:: /reference/constraints/_empty-values-are-valid.rst.inc
+
+==========  ===================================================================
+Applies to  :ref:`property or method <validation-property-target>`
+Class       :class:`Symfony\\Component\\Validator\\Constraints\\Slug`
+Validator   :class:`Symfony\\Component\\Validator\\Constraints\\SlugValidator`
+==========  ===================================================================
+
+Basic Usage
+-----------
+
+The ``Slug`` constraint can be applied to a property or a getter method:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Entity/Author.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+
+        class Author
+        {
+            #[Assert\Slug]
+            protected string $slug;
+        }
+
+    .. code-block:: yaml
+
+        # config/validator/validation.yaml
+        App\Entity\Author:
+            properties:
+                slug:
+                    - Slug: ~
+
+    .. code-block:: xml
+
+        <!-- config/validator/validation.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
+
+            <class name="App\Entity\Author">
+                <property name="slug">
+                    <constraint name="Slug"/>
+                </property>
+            </class>
+        </constraint-mapping>
+
+    .. code-block:: php
+
+        // src/Entity/Author.php
+        namespace App\Entity;
+
+        use Symfony\Component\Validator\Constraints as Assert;
+        use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+        class Author
+        {
+            // ...
+
+            public static function loadValidatorMetadata(ClassMetadata $metadata): void
+            {
+                $metadata->addPropertyConstraint('slug', new Assert\Slug());
+            }
+        }
+
+Examples of valid values:
+
+* foobar
+* foo-bar
+* foo123
+* foo-123bar
+
+Uppercase characters would result in an violation of this constraint.
+
+Options
+-------
+
+``regex``
+~~~~~~~~~
+
+**type**: ``string`` default: ``/^[a-z0-9]+(?:-[a-z0-9]+)*$/``
+
+This option allows you to modify the regular expression pattern that the input
+will be matched against via the :phpfunction:`preg_match` PHP function.
+
+If you need to use it, you might also want to take a look at the :doc:`Regex constraint <Regex>`.
+
+``message``
+~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``This value is not a valid slug``
+
+This is the message that will be shown if this validator fails.
+
+You can use the following parameters in this message:
+
+=================  ==============================================================
+Parameter          Description
+=================  ==============================================================
+``{{ value }}``    The current (invalid) value
+=================  ==============================================================
+
+.. include:: /reference/constraints/_groups-option.rst.inc
+
+.. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/UniqueEntity.rst b/reference/constraints/UniqueEntity.rst
index 87bdade534a..d4fbfeb8666 100644
--- a/reference/constraints/UniqueEntity.rst
+++ b/reference/constraints/UniqueEntity.rst
@@ -126,14 +126,14 @@ between all of the rows in your user table:
             }
         }
 
-.. caution::
+.. warning::
 
     This constraint doesn't provide any protection against `race conditions`_.
     They may occur when another entity is persisted by an external process after
     this validation has passed and before this entity is actually persisted in
     the database.
 
-.. caution::
+.. warning::
 
     This constraint cannot deal with duplicates found in a collection of items
     that haven't been persisted as entities yet. You'll need to create your own
@@ -355,7 +355,7 @@ this option to specify one or more fields to only ignore ``null`` values on them
             }
         }
 
-.. caution::
+.. warning::
 
     If you ``ignoreNull`` on fields that are part of a unique index in your
     database, you might see insertion errors when your application attempts to
diff --git a/reference/constraints/_payload-option.rst.inc b/reference/constraints/_payload-option.rst.inc
index a76c9a4a29d..5121ba1ae51 100644
--- a/reference/constraints/_payload-option.rst.inc
+++ b/reference/constraints/_payload-option.rst.inc
@@ -1,5 +1,3 @@
-.. _reference-constraints-payload:
-
 ``payload``
 ~~~~~~~~~~~
 
diff --git a/reference/constraints/map.rst.inc b/reference/constraints/map.rst.inc
index f23f5b71aa3..58801a8c653 100644
--- a/reference/constraints/map.rst.inc
+++ b/reference/constraints/map.rst.inc
@@ -33,6 +33,7 @@ String Constraints
 * :doc:`NotCompromisedPassword </reference/constraints/NotCompromisedPassword>`
 * :doc:`PasswordStrength </reference/constraints/PasswordStrength>`
 * :doc:`Regex </reference/constraints/Regex>`
+* :doc:`Slug </reference/constraints/Slug>`
 * :doc:`Ulid </reference/constraints/Ulid>`
 * :doc:`Url </reference/constraints/Url>`
 * :doc:`UserPassword </reference/constraints/UserPassword>`
diff --git a/reference/dic_tags.rst b/reference/dic_tags.rst
index 7caaf5447e0..866aac5774f 100644
--- a/reference/dic_tags.rst
+++ b/reference/dic_tags.rst
@@ -335,7 +335,7 @@ controller.argument_value_resolver
 Value resolvers implement the
 :class:`Symfony\\Component\\HttpKernel\\Controller\\ValueResolverInterface`
 and are used to resolve argument values for controllers as described here:
-:doc:`/controller/argument_value_resolver`.
+:doc:`/controller/value_resolver`.
 
 data_collector
 --------------
@@ -560,7 +560,7 @@ can also register it manually:
     that defaults to ``0``. The higher the number, the earlier that warmers are
     executed.
 
-.. caution::
+.. warning::
 
     If your cache warmer fails its execution because of any exception, Symfony
     won't try to execute it again for the next requests. Therefore, your
diff --git a/reference/formats/expression_language.rst b/reference/formats/expression_language.rst
index 368c95bc2a8..dfed9c74398 100644
--- a/reference/formats/expression_language.rst
+++ b/reference/formats/expression_language.rst
@@ -26,7 +26,7 @@ The component supports:
 
     The support for comments inside expressions was introduced in Symfony 7.2.
 
-.. caution::
+.. warning::
 
     A backslash (``\``) must be escaped by 3 backslashes (``\\\\``) in a string
     and 7 backslashes (``\\\\\\\\``) in a regex::
diff --git a/reference/formats/message_format.rst b/reference/formats/message_format.rst
index 2a694ed45d2..fb0143228c1 100644
--- a/reference/formats/message_format.rst
+++ b/reference/formats/message_format.rst
@@ -64,7 +64,7 @@ The basic usage of the MessageFormat allows you to use placeholders (called
             'say_hello' => "Hello {name}!",
         ];
 
-.. caution::
+.. warning::
 
     In the previous translation format, placeholders were often wrapped in ``%``
     (e.g. ``%name%``). This ``%`` character is no longer valid with the ICU
diff --git a/reference/forms/types/choice.rst b/reference/forms/types/choice.rst
index 2d31aac890c..9f61fb768bd 100644
--- a/reference/forms/types/choice.rst
+++ b/reference/forms/types/choice.rst
@@ -93,7 +93,7 @@ method::
 You can also customize the `choice_name`_ of each choice. You can learn more
 about all of these options in the sections below.
 
-.. caution::
+.. warning::
 
     The *placeholder* is a specific field, when the choices are optional the
     first item in the list must be empty, so the user can unselect.
diff --git a/reference/forms/types/collection.rst b/reference/forms/types/collection.rst
index c5fee42f06c..2875ba076d0 100644
--- a/reference/forms/types/collection.rst
+++ b/reference/forms/types/collection.rst
@@ -99,7 +99,7 @@ can be used - with JavaScript - to create new form items dynamically on
 the client side. For more information, see the above example and
 :ref:`form-collections-new-prototype`.
 
-.. caution::
+.. warning::
 
     If you're embedding entire other forms to reflect a one-to-many database
     relationship, you may need to manually ensure that the foreign key of
@@ -119,7 +119,7 @@ submitted data will mean that it's removed from the final array.
 
 For more information, see :ref:`form-collections-remove`.
 
-.. caution::
+.. warning::
 
     Be careful when using this option when you're embedding a collection
     of objects. In this case, if any embedded forms are removed, they *will*
@@ -139,7 +139,7 @@ form you have to set this option to ``true``. However, existing collection entri
 will only be deleted if you have the allow_delete_ option enabled. Otherwise
 the empty values will be kept.
 
-.. caution::
+.. warning::
 
     The ``delete_empty`` option only removes items when the normalized value is
     ``null``. If the nested `entry_type`_ is a compound form type, you must
diff --git a/reference/forms/types/country.rst b/reference/forms/types/country.rst
index d841461b2f5..6c98897b6ba 100644
--- a/reference/forms/types/country.rst
+++ b/reference/forms/types/country.rst
@@ -52,7 +52,7 @@ Overridden Options
 The country type defaults the ``choices`` option to the whole list of countries.
 The locale is used to translate the countries names.
 
-.. caution::
+.. warning::
 
     If you want to override the built-in choices of the country type, you
     will also have to set the ``choice_loader`` option to ``null``.
diff --git a/reference/forms/types/currency.rst b/reference/forms/types/currency.rst
index b69225eb78c..94c0d2cddc8 100644
--- a/reference/forms/types/currency.rst
+++ b/reference/forms/types/currency.rst
@@ -35,7 +35,7 @@ Overridden Options
 
 The choices option defaults to all currencies.
 
-.. caution::
+.. warning::
 
     If you want to override the built-in choices of the currency type, you
     will also have to set the ``choice_loader`` option to ``null``.
diff --git a/reference/forms/types/date.rst b/reference/forms/types/date.rst
index e88e91d80dd..210fff5dd0d 100644
--- a/reference/forms/types/date.rst
+++ b/reference/forms/types/date.rst
@@ -101,7 +101,7 @@ This can be tricky: if the date picker is misconfigured, Symfony won't understan
 the format and will throw a validation error. You can also configure the format
 that Symfony should expect via the `format`_ option.
 
-.. caution::
+.. warning::
 
     The string used by a JavaScript date picker to describe its format (e.g. ``yyyy-mm-dd``)
     may not match the string that Symfony uses (e.g. ``yyyy-MM-dd``). This is because
@@ -156,11 +156,12 @@ values for the year, month and day fields::
 ``calendar``
 ~~~~~~~~~~~~
 
-**type**: ``\IntlCalendar`` **default**: ``null``
+**type**: ``integer`` or ``\IntlCalendar`` **default**: ``null``
 
 The calendar to use for formatting and parsing the date. The value should be
-an instance of the :phpclass:`IntlCalendar` to use. By default, the Gregorian
-calendar with the application default locale is used.
+an ``integer`` from :phpclass:`IntlDateFormatter` calendar constants or an instance
+of the :phpclass:`IntlCalendar` to use. By default, the Gregorian calendar
+with the application default locale is used.
 
 .. versionadded:: 7.2
 
diff --git a/reference/forms/types/dateinterval.rst b/reference/forms/types/dateinterval.rst
index 38fccb47cd1..838ae2bbdef 100644
--- a/reference/forms/types/dateinterval.rst
+++ b/reference/forms/types/dateinterval.rst
@@ -221,7 +221,7 @@ following:
 Whether or not to include days in the input. This will result in an additional
 input to capture days.
 
-.. caution::
+.. warning::
 
     This can not be used when `with_weeks`_ is enabled.
 
@@ -274,7 +274,7 @@ input to capture seconds.
 Whether or not to include weeks in the input. This will result in an additional
 input to capture weeks.
 
-.. caution::
+.. warning::
 
     This can not be used when `with_days`_ is enabled.
 
diff --git a/reference/forms/types/entity.rst b/reference/forms/types/entity.rst
index f30d5f9a5b2..0d900de377f 100644
--- a/reference/forms/types/entity.rst
+++ b/reference/forms/types/entity.rst
@@ -183,7 +183,7 @@ passed the ``EntityRepository`` of the entity as the only argument and should
 return a ``QueryBuilder``. Returning ``null`` in the Closure will result in
 loading all entities.
 
-.. caution::
+.. warning::
 
     The entity used in the ``FROM`` clause of the ``query_builder`` option
     will always be validated against the class which you have specified at the
diff --git a/reference/forms/types/language.rst b/reference/forms/types/language.rst
index e3dddfb8ae6..a1e699a0686 100644
--- a/reference/forms/types/language.rst
+++ b/reference/forms/types/language.rst
@@ -69,7 +69,7 @@ Overridden Options
 The choices option defaults to all languages.
 The default locale is used to translate the languages names.
 
-.. caution::
+.. warning::
 
     If you want to override the built-in choices of the language type, you
     will also have to set the ``choice_loader`` option to ``null``.
diff --git a/reference/forms/types/locale.rst b/reference/forms/types/locale.rst
index 68155a248fd..c006beb14fd 100644
--- a/reference/forms/types/locale.rst
+++ b/reference/forms/types/locale.rst
@@ -46,7 +46,7 @@ Overridden Options
 The choices option defaults to all locales. It uses the default locale to
 specify the language.
 
-.. caution::
+.. warning::
 
     If you want to override the built-in choices of the locale type, you
     will also have to set the ``choice_loader`` option to ``null``.
diff --git a/reference/forms/types/money.rst b/reference/forms/types/money.rst
index f9f8cefdd58..a02b695abd4 100644
--- a/reference/forms/types/money.rst
+++ b/reference/forms/types/money.rst
@@ -70,9 +70,10 @@ html5
 If set to ``true``, the HTML input will be rendered as a native HTML5
 ``<input type="number">`` element.
 
-.. caution::
+.. warning::
 
-    As HTML5 number format is normalized, it is incompatible with ``grouping`` option.
+    As HTML5 number format is normalized, it is incompatible with the ``grouping``
+    option.
 
 input
 ~~~~~
diff --git a/reference/forms/types/options/_date_limitation.rst.inc b/reference/forms/types/options/_date_limitation.rst.inc
index 4e5b1be4c87..04106ee7e21 100644
--- a/reference/forms/types/options/_date_limitation.rst.inc
+++ b/reference/forms/types/options/_date_limitation.rst.inc
@@ -1,4 +1,4 @@
-.. caution::
+.. warning::
 
     If ``timestamp`` is used, ``DateType`` is limited to dates between
     Fri, 13 Dec 1901 20:45:54 UTC and Tue, 19 Jan 2038 03:14:07 UTC on 32bit
diff --git a/reference/forms/types/options/choice_lazy.rst.inc b/reference/forms/types/options/choice_lazy.rst.inc
index bdcbf178406..08fbe953e41 100644
--- a/reference/forms/types/options/choice_lazy.rst.inc
+++ b/reference/forms/types/options/choice_lazy.rst.inc
@@ -24,7 +24,7 @@ will only load and render the choices that are preset as default values or
 submitted. This defers the loading of the full list of choices, helping to
 improve your form's performance.
 
-.. caution::
+.. warning::
 
     Keep in mind that when using ``choice_lazy``, you are responsible for
     providing the user interface for selecting choices, typically through a
diff --git a/reference/forms/types/options/choice_name.rst.inc b/reference/forms/types/options/choice_name.rst.inc
index 4ec8abb6ffe..4268c307d17 100644
--- a/reference/forms/types/options/choice_name.rst.inc
+++ b/reference/forms/types/options/choice_name.rst.inc
@@ -25,7 +25,7 @@ By default, the choice key or an incrementing integer may be used (starting at `
 
     See the :ref:`"choice_loader" option documentation <reference-form-choice-loader>`.
 
-.. caution::
+.. warning::
 
     The configured value must be a valid form name. Make sure to only return
     valid names when using a callable. Valid form names must be composed of
diff --git a/reference/forms/types/options/data.rst.inc b/reference/forms/types/options/data.rst.inc
index c3562d0a8b1..34f86e7c4c6 100644
--- a/reference/forms/types/options/data.rst.inc
+++ b/reference/forms/types/options/data.rst.inc
@@ -16,7 +16,7 @@ an individual field, you can set it in the data option::
         'data' => 'abcdef',
     ]);
 
-.. caution::
+.. warning::
 
     The ``data`` option *always* overrides the value taken from the domain data
     (object) when rendering. This means the object value is also overridden when
diff --git a/reference/forms/types/options/empty_data_description.rst.inc b/reference/forms/types/options/empty_data_description.rst.inc
index e654a7037df..b143b9438fe 100644
--- a/reference/forms/types/options/empty_data_description.rst.inc
+++ b/reference/forms/types/options/empty_data_description.rst.inc
@@ -22,7 +22,7 @@ initial value in the rendered form.
     :doc:`/form/use_empty_data` article for more details about these
     options.
 
-.. caution::
+.. warning::
 
     :doc:`Form data transformers </form/data_transformers>` will still be
     applied to the ``empty_data`` value. This means that an empty string will
diff --git a/reference/forms/types/options/inherit_data.rst.inc b/reference/forms/types/options/inherit_data.rst.inc
index 1b63cc4b56f..f35f6d56b00 100644
--- a/reference/forms/types/options/inherit_data.rst.inc
+++ b/reference/forms/types/options/inherit_data.rst.inc
@@ -7,7 +7,7 @@ This option determines if the form will inherit data from its parent form.
 This can be useful if you have a set of fields that are duplicated across
 multiple forms. See :doc:`/form/inherit_data_option`.
 
-.. caution::
+.. warning::
 
     When a field has the ``inherit_data`` option set, it uses the data of
     the parent form as is. This means that
diff --git a/reference/forms/types/options/value.rst.inc b/reference/forms/types/options/value.rst.inc
index ddbfff6660d..e4669faa7e4 100644
--- a/reference/forms/types/options/value.rst.inc
+++ b/reference/forms/types/options/value.rst.inc
@@ -6,7 +6,7 @@
 The value that's actually used as the value for the checkbox or radio button.
 This does not affect the value that's set on your object.
 
-.. caution::
+.. warning::
 
     To make a checkbox or radio button checked by default, use the `data`_
     option.
diff --git a/reference/forms/types/password.rst b/reference/forms/types/password.rst
index 83342194a4e..59e40fb19d1 100644
--- a/reference/forms/types/password.rst
+++ b/reference/forms/types/password.rst
@@ -43,7 +43,7 @@ Data passed to the form must be a
 :class:`Symfony\\Component\\Security\\Core\\User\\PasswordAuthenticatedUserInterface`
 object.
 
-.. caution::
+.. warning::
 
     To minimize the risk of leaking the plain password, this option can
     only be used with the :ref:`"mapped" option <reference-form-password-mapped>`
diff --git a/reference/forms/types/textarea.rst b/reference/forms/types/textarea.rst
index cf56d3067de..47a32368b99 100644
--- a/reference/forms/types/textarea.rst
+++ b/reference/forms/types/textarea.rst
@@ -19,7 +19,7 @@ Renders a ``textarea`` HTML element.
     ``<textarea>``, consider using the FOSCKEditorBundle community bundle. Read
     `its documentation`_ to learn how to integrate it in your Symfony application.
 
-.. caution::
+.. warning::
 
     When allowing users to type HTML code in the textarea (or using a
     WYSIWYG) editor, the application is vulnerable to :ref:`XSS injection <xss-attacks>`,
diff --git a/reference/forms/types/time.rst b/reference/forms/types/time.rst
index 43cf0644e0e..a3378f948cd 100644
--- a/reference/forms/types/time.rst
+++ b/reference/forms/types/time.rst
@@ -80,6 +80,10 @@ values for the hour, minute and second fields::
         ],
     ]);
 
+.. seealso::
+
+    See the `with_seconds`_ option on how to enable seconds in the form type.
+
 .. include:: /reference/forms/types/options/hours.rst.inc
 
 .. include:: /reference/forms/types/options/html5.rst.inc
@@ -113,7 +117,7 @@ of the time. This must be a valid `PHP time format`_.
 
 .. include:: /reference/forms/types/options/model_timezone.rst.inc
 
-.. caution::
+.. warning::
 
     When using different values for ``model_timezone`` and `view_timezone`_,
     a `reference_date`_ must be configured.
@@ -134,7 +138,7 @@ based on this date.
 When no `reference_date`_ is set the ``view_timezone`` defaults to the
 configured `model_timezone`_.
 
-.. caution::
+.. warning::
 
     When using different values for `model_timezone`_ and ``view_timezone``,
     a `reference_date`_ must be configured.
@@ -157,7 +161,7 @@ following:
   will be validated against the form ``hh:mm`` (or ``hh:mm:ss`` if using
   seconds).
 
-.. caution::
+.. warning::
 
     Combining the widget type ``single_text`` and the `with_minutes`_ option
     set to ``false`` can cause unexpected behavior in the client as the
diff --git a/reference/forms/types/timezone.rst b/reference/forms/types/timezone.rst
index 7dae0f351b4..d2af713f1c8 100644
--- a/reference/forms/types/timezone.rst
+++ b/reference/forms/types/timezone.rst
@@ -67,7 +67,7 @@ Overridden Options
 The Timezone type defaults the choices to all timezones returned by
 :phpmethod:`DateTimeZone::listIdentifiers`, broken down by continent.
 
-.. caution::
+.. warning::
 
     If you want to override the built-in choices of the timezone type, you
     will also have to set the ``choice_loader`` option to ``null``.
diff --git a/reference/forms/types/url.rst b/reference/forms/types/url.rst
index d4cb312d2bb..9c6dde6072e 100644
--- a/reference/forms/types/url.rst
+++ b/reference/forms/types/url.rst
@@ -25,6 +25,13 @@ Field Options
 
 **type**: ``string`` **default**: ``http``
 
+Set this value to ``null`` to render the field using a ``<input type="url"/>``,
+allowing the browser to perform local validation before submission.
+
+When this value is neither ``null`` nor an empty string, the form field is
+rendered using a ``<input type="text"/>``. This ensures users can submit the
+form field without specifying the protocol.
+
 If a value is submitted that doesn't begin with some protocol (e.g. ``http://``,
 ``ftp://``, etc), this protocol will be prepended to the string when
 the data is submitted to the form.
diff --git a/reference/twig_reference.rst b/reference/twig_reference.rst
index 0939e2bdf98..acbab2f3817 100644
--- a/reference/twig_reference.rst
+++ b/reference/twig_reference.rst
@@ -130,8 +130,10 @@ asset_version
 
 .. code-block:: twig
 
-    {{ asset_version(packageName = null) }}
+    {{ asset_version(path, packageName = null) }}
 
+``path``
+    **type**: ``string``
 ``packageName`` *(optional)*
     **type**: ``string`` | ``null`` **default**: ``null``
 
@@ -158,20 +160,41 @@ is_granted
 
 .. code-block:: twig
 
-    {{ is_granted(role, object = null, field = null) }}
+    {{ is_granted(role, object = null) }}
 
 ``role``
     **type**: ``string``
 ``object`` *(optional)*
     **type**: ``object``
-``field`` *(optional)*
-    **type**: ``string``
 
 Returns ``true`` if the current user has the given role.
 
 Optionally, an object can be passed to be used by the voter. More information
 can be found in :ref:`security-template`.
 
+is_granted_for_user
+~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 7.3
+
+    The ``is_granted_for_user()`` function was introduced in Symfony 7.3.
+
+.. code-block:: twig
+
+    {{ is_granted_for_user(user, attribute, subject = null) }}
+
+``user``
+    **type**: ``object``
+``attribute``
+    **type**: ``string``
+``subject`` *(optional)*
+    **type**: ``object``
+
+Returns ``true`` if the user is authorized for the specified attribute.
+
+Optionally, an object can be passed to be used by the voter. More information
+can be found in :ref:`security-template`.
+
 logout_path
 ~~~~~~~~~~~
 
@@ -701,6 +724,8 @@ project's root directory:
 If the given file path is out of the project directory, a ``null`` value
 will be returned.
 
+.. _reference-twig-filter-serialize:
+
 serialize
 ~~~~~~~~~
 
diff --git a/routing.rst b/routing.rst
index 18f96270e1c..4ab0dce2a82 100644
--- a/routing.rst
+++ b/routing.rst
@@ -81,7 +81,7 @@ the ``list()`` method of the ``BlogController`` class.
     example, URLs like ``/blog?foo=bar`` and ``/blog?foo=bar&bar=foo`` will
     also match the ``blog_list`` route.
 
-.. caution::
+.. warning::
 
     If you define multiple PHP classes in the same file, Symfony only loads the
     routes of the first class, ignoring all the other routes.
@@ -298,7 +298,7 @@ arbitrary matching logic:
         # config/routes.yaml
         contact:
             path:       /contact
-            controller: 'App\Controller\DefaultController::contact'
+            controller: App\Controller\DefaultController::contact
             condition:  "context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i'"
             # expressions can also include configuration parameters:
             # condition: "request.headers.get('User-Agent') matches '%app.allowed_browsers%'"
@@ -307,7 +307,7 @@ arbitrary matching logic:
 
         post_show:
             path:       /posts/{id}
-            controller: 'App\Controller\DefaultController::showPost'
+            controller: App\Controller\DefaultController::showPost
             # expressions can retrieve route parameter values using the "params" variable
             condition:  "params['id'] < 1000"
 
@@ -406,7 +406,7 @@ Behind the scenes, expressions are compiled down to raw PHP. Because of this,
 using the ``condition`` key causes no extra overhead beyond the time it takes
 for the underlying PHP to execute.
 
-.. caution::
+.. warning::
 
     Conditions are *not* taken into account when generating URLs (which is
     explained later in this article).
@@ -649,6 +649,51 @@ URL                       Route          Parameters
     contains a collection of commonly used regular-expression constants such as
     digits, dates and UUIDs which can be used as route parameter requirements.
 
+    .. configuration-block::
+
+        .. code-block:: php-attributes
+
+            // src/Controller/BlogController.php
+            namespace App\Controller;
+
+            use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+            use Symfony\Component\HttpFoundation\Response;
+            use Symfony\Component\Routing\Attribute\Route;
+            use Symfony\Component\Routing\Requirement\Requirement;
+
+            class BlogController extends AbstractController
+            {
+                #[Route('/blog/{page}', name: 'blog_list', requirements: ['page' => Requirement::DIGITS])]
+                public function list(int $page): Response
+                {
+                    // ...
+                }
+            }
+
+        .. code-block:: yaml
+
+            # config/routes.yaml
+            blog_list:
+                path:       /blog/{page}
+                controller: App\Controller\BlogController::list
+                requirements:
+                    page: !php/const Symfony\Component\Routing\Requirement\Requirement::DIGITS
+
+        .. code-block:: php
+
+            // config/routes.php
+            use App\Controller\BlogController;
+            use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
+            use Symfony\Component\Routing\Requirement\Requirement;
+
+            return static function (RoutingConfigurator $routes): void {
+                $routes->add('blog_list', '/blog/{page}')
+                    ->controller([BlogController::class, 'list'])
+                    ->requirements(['page' => Requirement::DIGITS])
+                ;
+                // ...
+            };
+
 .. tip::
 
     Route requirements (and route paths too) can include
@@ -808,7 +853,7 @@ other configuration formats they are defined with the ``defaults`` option:
 Now, when the user visits ``/blog``, the ``blog_list`` route will match and
 ``$page`` will default to a value of ``1``.
 
-.. caution::
+.. warning::
 
     You can have more than one optional parameter (e.g. ``/blog/{slug}/{page}``),
     but everything after an optional parameter must be optional. For example,
@@ -1489,6 +1534,12 @@ when importing the routes.
             ;
         };
 
+.. warning::
+
+    The ``exclude`` option only works when the ``resource`` value is a glob string.
+    If you use a regular string (e.g. ``'../src/Controller'``) the ``exclude``
+    value will be ignored.
+
 In this example, the route of the ``index()`` action will be called ``blog_index``
 and its URL will be ``/blog/{_locale}``. The route of the ``show()`` action will be called
 ``blog_show`` and its URL will be ``/blog/{_locale}/posts/{slug}``. Both routes
@@ -2291,7 +2342,7 @@ use the ``generateUrl()`` helper::
         // the 'blog' route only defines the 'page' parameter; the generated URL is:
         // /blog/2?category=Symfony
 
-.. caution::
+.. warning::
 
     While objects are converted to string when used as placeholders, they are not
     converted when used as extra parameters. So, if you're passing an object (e.g. an Uuid)
@@ -2321,7 +2372,7 @@ the :class:`Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface` class
     class SomeService
     {
         public function __construct(
-            private UrlGeneratorInterface $router,
+            private UrlGeneratorInterface $urlGenerator,
         ) {
         }
 
@@ -2330,20 +2381,20 @@ the :class:`Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface` class
             // ...
 
             // generate a URL with no route arguments
-            $signUpPage = $this->router->generate('sign_up');
+            $signUpPage = $this->urlGenerator->generate('sign_up');
 
             // generate a URL with route arguments
-            $userProfilePage = $this->router->generate('user_profile', [
+            $userProfilePage = $this->urlGenerator->generate('user_profile', [
                 'username' => $user->getUserIdentifier(),
             ]);
 
             // generated URLs are "absolute paths" by default. Pass a third optional
             // argument to generate different URLs (e.g. an "absolute URL")
-            $signUpPage = $this->router->generate('sign_up', [], UrlGeneratorInterface::ABSOLUTE_URL);
+            $signUpPage = $this->urlGenerator->generate('sign_up', [], UrlGeneratorInterface::ABSOLUTE_URL);
 
             // when a route is localized, Symfony uses by default the current request locale
             // pass a different '_locale' value if you want to set the locale explicitly
-            $signUpPageInDutch = $this->router->generate('sign_up', ['_locale' => 'nl']);
+            $signUpPageInDutch = $this->urlGenerator->generate('sign_up', ['_locale' => 'nl']);
         }
     }
 
@@ -2751,6 +2802,11 @@ argument of :method:`Symfony\\Component\\HttpFoundation\\UriSigner::sign`::
 
     The feature to add an expiration date for a signed URI was introduced in Symfony 7.1.
 
+.. versionadded:: 7.3
+
+    Starting with Symfony 7.3, signed URI hashes no longer include the ``/`` or
+    ``+`` characters, as these may cause issues with certain clients.
+
 Troubleshooting
 ---------------
 
diff --git a/scheduler.rst b/scheduler.rst
index c816e6e08c0..c0db986d8c0 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -785,6 +785,13 @@ the Messenger component:
 .. image:: /_images/components/scheduler/generate_consume.png
     :alt: Symfony Scheduler - generate and consume
 
+.. tip::
+
+    Depending on your deployment scenario, you may prefer automating the execution of
+    the Messenger worker process using tools like cron, Supervisor, or systemd.
+    This ensures workers are running continuously. For more details, refer to the
+    `Deploying to Production`_ section of the Messenger component documentation.
+
 Creating a Consumer Programmatically
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -970,6 +977,7 @@ When using the ``RedispatchMessage``, Symfony will attach a
 helping you identify those messages when needed.
 
 .. _`MakerBundle`: https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html
+.. _`Deploying to Production`: https://symfony.com/doc/current/messenger.html#deploying-to-production
 .. _`Memoizing`: https://en.wikipedia.org/wiki/Memoization
 .. _`cron command-line utility`: https://en.wikipedia.org/wiki/Cron
 .. _`crontab.guru website`: https://crontab.guru/
diff --git a/security.rst b/security.rst
index 232188fe257..ca910765be0 100644
--- a/security.rst
+++ b/security.rst
@@ -712,7 +712,7 @@ many other authenticators:
 
     If your application logs users in via a third-party service such as
     Google, Facebook or Twitter (social login), check out the `HWIOAuthBundle`_
-    community bundle.
+    community bundle or `Oauth2-client`_ package.
 
 .. _security-form-login:
 
@@ -890,7 +890,7 @@ Finally, create or update the template:
         </form>
     {% endblock %}
 
-.. caution::
+.. warning::
 
     The ``error`` variable passed into the template is an instance
     of :class:`Symfony\\Component\\Security\\Core\\Exception\\AuthenticationException`.
@@ -1016,7 +1016,7 @@ be ``authenticate``:
     <form action="{{ path('app_login') }}" method="post">
         {# ... the login fields #}
 
-        <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
+        <input type="hidden" name="_csrf_token" data-controller="csrf-protection" value="{{ csrf_token('authenticate') }}">
 
         <button type="submit">login</button>
     </form>
@@ -1744,7 +1744,7 @@ You can log in a user programmatically using the ``login()`` method of the
 :class:`Symfony\\Bundle\\SecurityBundle\\Security` helper::
 
     // src/Controller/SecurityController.php
-    namespace App\Controller\SecurityController;
+    namespace App\Controller;
 
     use App\Security\Authenticator\ExampleAuthenticator;
     use Symfony\Bundle\SecurityBundle\Security;
@@ -2254,7 +2254,7 @@ Users with ``ROLE_SUPER_ADMIN``, will automatically have ``ROLE_ADMIN``,
 ``ROLE_ALLOWED_TO_SWITCH`` and ``ROLE_USER`` (inherited from
 ``ROLE_ADMIN``).
 
-.. caution::
+.. warning::
 
     For role hierarchy to work, do not use ``$user->getRoles()`` manually.
     For example, in a controller extending from the :ref:`base controller <the-base-controller-class-services>`::
@@ -2549,6 +2549,17 @@ the built-in ``is_granted()`` helper function in any Twig template:
 
 .. _security-isgranted:
 
+Similarly, if you want to check if a specific user has a certain role, you can use
+the built-in ``is_granted_for_user()`` helper function:
+
+.. code-block:: html+twig
+
+    {% if is_granted_for_user(user, 'ROLE_ADMIN') %}
+        <a href="...">Delete</a>
+    {% endif %}
+
+.. _security-isgrantedforuser:
+
 Securing other Services
 .......................
 
@@ -2585,6 +2596,19 @@ want to include extra details only for users that have a ``ROLE_SALES_ADMIN`` ro
           // ...
       }
 
+
+.. tip::
+
+    The ``isGranted()`` method checks authorization for the currently logged-in user.
+    If you need to check authorization for a different user or when the user session
+    is unavailable (e.g., in a CLI context such as a message queue or cron job), you
+    can use the ``isGrantedForUser()`` method to explicitly set the target user.
+
+    .. versionadded:: 7.3
+
+        The :method:`Symfony\\Bundle\\SecurityBundle\\Security::isGrantedForUser`
+        method was introduced in Symfony 7.3.
+
 If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`,
 Symfony will automatically pass the ``security.helper`` to your service
 thanks to autowiring and the ``Security`` type-hint.
@@ -2782,6 +2806,8 @@ implement :class:`Symfony\\Component\\Security\\Core\\User\\EquatableInterface`.
 Then, your ``isEqualTo()`` method will be called when comparing users instead
 of the core logic.
 
+.. _security-security-events:
+
 Security Events
 ---------------
 
@@ -2972,3 +2998,4 @@ Authorization (Denying Access)
 .. _`HTTP Basic authentication`: https://en.wikipedia.org/wiki/Basic_access_authentication
 .. _`Login CSRF attacks`: https://en.wikipedia.org/wiki/Cross-site_request_forgery#Forging_login_requests
 .. _`PHP date relative formats`: https://www.php.net/manual/en/datetime.formats.php#datetime.formats.relative
+.. _`Oauth2-client`: https://github.com/thephpleague/oauth2-client
diff --git a/security/access_control.rst b/security/access_control.rst
index cd94c930592..8e62e8a84c7 100644
--- a/security/access_control.rst
+++ b/security/access_control.rst
@@ -213,7 +213,7 @@ Example #7:
   * **Why?** This doesn't match any ``access_control`` rules, since its URI
   * doesn't match any of the ``path`` values.
 
-.. caution::
+.. warning::
 
     Matching the URI is done without ``$_GET`` parameters.
     :ref:`Deny access in PHP code <security-securing-controller>` if you want
@@ -246,7 +246,7 @@ options:
     can learn how to use your custom attributes by reading
     :ref:`security/custom-voter`.
 
-.. caution::
+.. warning::
 
     If you define both ``roles`` and ``allow_if``, and your Access Decision
     Strategy is the default one (``affirmative``), then the user will be granted
@@ -268,7 +268,7 @@ entry that *only* matches requests coming from some IP address or range.
 For example, this *could* be used to deny access to a URL pattern to all
 requests *except* those from a trusted, internal server.
 
-.. caution::
+.. warning::
 
     As you'll read in the explanation below the example, the ``ips`` option
     does not restrict to a specific IP address. Instead, using the ``ips``
diff --git a/security/access_token.rst b/security/access_token.rst
index 114c4b8964a..c0ff4692676 100644
--- a/security/access_token.rst
+++ b/security/access_token.rst
@@ -107,7 +107,7 @@ This handler must implement
 The access token authenticator will use the returned user identifier to
 load the user using the :ref:`user provider <security-user-providers>`.
 
-.. caution::
+.. warning::
 
     It is important to check the token if is valid. For instance, the
     example above verifies whether the token has not expired. With
@@ -136,7 +136,7 @@ Symfony provides other extractors as per the `RFC6750`_:
     The token is part of the request body during a POST request. Usually
     ``access_token``.
 
-.. caution::
+.. warning::
 
     Because of the security weaknesses associated with the URI method,
     including the high likelihood that the URL or the request body
diff --git a/security/custom_authenticator.rst b/security/custom_authenticator.rst
index 689df6108e3..8b2ec9d7f34 100644
--- a/security/custom_authenticator.rst
+++ b/security/custom_authenticator.rst
@@ -153,22 +153,25 @@ or there was something wrong (e.g. incorrect password). The authenticator
 can define what happens in these cases:
 
 ``onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response``
-    If the user is authenticated, this method is called with the
-    authenticated ``$token``. This method can return a response (e.g.
-    redirect the user to some page).
+    If authentication is successful, this method is called with the
+    authenticated ``$token``.
 
-    If ``null`` is returned, the request continues like normal (i.e. the
-    controller matching the login route is called). This is useful for API
-    routes where each route is protected by an API key header.
+    This method can return a response (e.g. redirect the user to some page).
+
+    If ``null`` is returned, the current request will continue (and the
+    user will be authenticated). This is useful for API routes where each
+    route is protected by an API key header.
 
 ``onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response``
-    If an ``AuthenticationException`` is thrown during authentication, the
-    process fails and this method is called. This method can return a
-    response (e.g. to return a 401 Unauthorized response in API routes).
+    If authentication failed (e. g. wrong username password), this method
+    is called with the ``AuthenticationException`` thrown.
+
+    This method can return a response (e.g. send a 401 Unauthorized in API
+    routes).
 
-    If ``null`` is returned, the request continues like normal. This is
-    useful for e.g. login forms, where the login controller is run again
-    with the login errors.
+    If ``null`` is returned, the request continues (but the user will **not**
+    be authenticated). This is useful for login forms, where the login
+    controller is run again with the login errors.
 
     If you're using :ref:`login throttling <security-login-throttling>`,
     you can check if ``$exception`` is an instance of
diff --git a/security/impersonating_user.rst b/security/impersonating_user.rst
index 41f055ea39a..6f22e7aace6 100644
--- a/security/impersonating_user.rst
+++ b/security/impersonating_user.rst
@@ -5,7 +5,7 @@ Sometimes, it's useful to be able to switch from one user to another without
 having to log out and log in again (for instance when you are debugging something
 a user sees that you can't reproduce).
 
-.. caution::
+.. warning::
 
     User impersonation is not compatible with some authentication mechanisms
     (e.g. ``REMOTE_USER``) where the authentication information is expected to be
@@ -368,13 +368,14 @@ logic you want::
 
     use Symfony\Bundle\SecurityBundle\Security;
     use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+    use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
     use Symfony\Component\Security\Core\Authorization\Voter\Voter;
     use Symfony\Component\Security\Core\User\UserInterface;
 
     class SwitchToCustomerVoter extends Voter
     {
         public function __construct(
-            private Security $security,
+            private AccessDecisionManagerInterface $accessDecisionManager,
         ) {
         }
 
@@ -393,12 +394,12 @@ logic you want::
             }
 
             // you can still check for ROLE_ALLOWED_TO_SWITCH
-            if ($this->security->isGranted('ROLE_ALLOWED_TO_SWITCH')) {
+            if ($this->accessDecisionManager->decide($token, ['ROLE_ALLOWED_TO_SWITCH'])) {
                 return true;
             }
 
             // check for any roles you want
-            if ($this->security->isGranted('ROLE_TECH_SUPPORT')) {
+            if ($this->accessDecisionManager->decide($token, ['ROLE_TECH_SUPPORT'])) {
                 return true;
             }
 
diff --git a/security/ldap.rst b/security/ldap.rst
index 6466178ee69..081be764290 100644
--- a/security/ldap.rst
+++ b/security/ldap.rst
@@ -197,14 +197,14 @@ use the ``ldap`` user provider.
             ;
         };
 
-.. caution::
+.. danger::
 
     The Security component escapes provided input data when the LDAP user
     provider is used. However, the LDAP component itself does not provide
     any escaping yet. Thus, it's your responsibility to prevent LDAP injection
     attacks when using the component directly.
 
-.. caution::
+.. warning::
 
     The user configured above in the user provider is only used to retrieve
     data. It's a static user defined by its username and password (for improved
diff --git a/security/login_link.rst b/security/login_link.rst
index e80a3cb27b0..57d353278c2 100644
--- a/security/login_link.rst
+++ b/security/login_link.rst
@@ -194,7 +194,7 @@ controller. Based on this property, the correct user is loaded and a login
 link is created using
 :method:`Symfony\\Component\\Security\\Http\\LoginLink\\LoginLinkHandlerInterface::createLoginLink`.
 
-.. caution::
+.. warning::
 
     It is important to send this link to the user and **not show it directly**,
     as that would allow anyone to login. For instance, use the
diff --git a/security/passwords.rst b/security/passwords.rst
index 09e01507dec..fe20187b3a0 100644
--- a/security/passwords.rst
+++ b/security/passwords.rst
@@ -644,7 +644,7 @@ the name of the hasher to use::
         }
     }
 
-.. caution::
+.. warning::
 
     When :ref:`migrating passwords <security-password-migration>`, you don't
     need to implement ``PasswordHasherAwareInterface`` to return the legacy
diff --git a/security/remember_me.rst b/security/remember_me.rst
index 8fac6d78849..2fd0f7e8d1e 100644
--- a/security/remember_me.rst
+++ b/security/remember_me.rst
@@ -19,7 +19,7 @@ the session lasts using a cookie with the ``remember_me`` firewall option:
                 main:
                     # ...
                     remember_me:
-                        secret:   '%kernel.secret%' # required
+                        secret: '%kernel.secret%'
                         lifetime: 604800 # 1 week in seconds
                         # by default, the feature is enabled by checking a
                         # checkbox in the login form (see below), uncomment the
@@ -44,7 +44,7 @@ the session lasts using a cookie with the ``remember_me`` firewall option:
                 <firewall name="main">
                     <!-- ... -->
 
-                    <!-- secret: required
+                    <!-- secret: default to "%kernel.secret%"
                          lifetime: 604800 is 1 week in seconds -->
                     <remember-me
                         secret="%kernel.secret%"
@@ -67,7 +67,7 @@ the session lasts using a cookie with the ``remember_me`` firewall option:
             $security->firewall('main')
                 // ...
                 ->rememberMe()
-                    ->secret('%kernel.secret%') // required
+                    ->secret('%kernel.secret%')
                     ->lifetime(604800) // 1 week in seconds
 
                     // by default, the feature is enabled by checking a
@@ -77,9 +77,11 @@ the session lasts using a cookie with the ``remember_me`` firewall option:
             ;
         };
 
-The ``secret`` option is the only required option and it is used to sign
-the remember me cookie. It's common to use the ``kernel.secret`` parameter,
-which is defined using the ``APP_SECRET`` environment variable.
+.. versionadded:: 7.2
+
+    The ``secret`` option is no longer required starting from Symfony 7.2. By
+    default, ``%kernel.secret%`` is used, which is defined using the
+    ``APP_SECRET`` environment variable.
 
 After enabling the ``remember_me`` system in the configuration, there are a
 couple more things to do before remember me works correctly:
@@ -171,7 +173,6 @@ allow users to opt-out. In these cases, you can use the
                 main:
                     # ...
                     remember_me:
-                        secret: '%kernel.secret%'
                         # ...
                         always_remember_me: true
 
@@ -194,7 +195,6 @@ allow users to opt-out. In these cases, you can use the
                     <!-- ... -->
 
                     <remember-me
-                        secret="%kernel.secret%"
                         always-remember-me="true"
                     />
                 </firewall>
@@ -211,7 +211,6 @@ allow users to opt-out. In these cases, you can use the
             $security->firewall('main')
                 // ...
                 ->rememberMe()
-                    ->secret('%kernel.secret%')
                     // ...
                     ->alwaysRememberMe(true)
             ;
@@ -335,7 +334,6 @@ are fetched from the user object using the
                 main:
                     # ...
                     remember_me:
-                        secret: '%kernel.secret%'
                         # ...
                         signature_properties: ['password', 'updatedAt']
 
@@ -357,7 +355,7 @@ are fetched from the user object using the
                 <firewall name="main">
                     <!-- ... -->
 
-                    <remember-me secret="%kernel.secret%">
+                    <remember-me>
                         <signature-property>password</signature-property>
                         <signature-property>updatedAt</signature-property>
                     </remember-me>
@@ -375,7 +373,6 @@ are fetched from the user object using the
             $security->firewall('main')
                 // ...
                 ->rememberMe()
-                    ->secret('%kernel.secret%')
                     // ...
                     ->signatureProperties(['password', 'updatedAt'])
             ;
@@ -419,7 +416,6 @@ You can enable the doctrine token provider using the ``doctrine`` setting:
                 main:
                     # ...
                     remember_me:
-                        secret: '%kernel.secret%'
                         # ...
                         token_provider:
                             doctrine: true
@@ -442,7 +438,7 @@ You can enable the doctrine token provider using the ``doctrine`` setting:
                 <firewall name="main">
                     <!-- ... -->
 
-                    <remember-me secret="%kernel.secret%">
+                    <remember-me>
                         <token-provider doctrine="true"/>
                     </remember-me>
                 </firewall>
@@ -459,7 +455,6 @@ You can enable the doctrine token provider using the ``doctrine`` setting:
             $security->firewall('main')
                 // ...
                 ->rememberMe()
-                    ->secret('%kernel.secret%')
                     // ...
                     ->tokenProvider([
                         'doctrine' => true,
diff --git a/security/user_providers.rst b/security/user_providers.rst
index 17a18468168..09d47c270f2 100644
--- a/security/user_providers.rst
+++ b/security/user_providers.rst
@@ -257,7 +257,7 @@ After setting up hashing, you can configure all the user information in
             ;
         };
 
-.. caution::
+.. warning::
 
     When using a ``memory`` provider, and not the ``auto`` algorithm, you have
     to choose an encoding without salt (i.e. ``bcrypt``).
diff --git a/security/voters.rst b/security/voters.rst
index 01be3eb0745..e7452fadf99 100644
--- a/security/voters.rst
+++ b/security/voters.rst
@@ -237,22 +237,22 @@ Checking for Roles inside a Voter
 ---------------------------------
 
 What if you want to call ``isGranted()`` from *inside* your voter - e.g. you want
-to see if the current user has ``ROLE_SUPER_ADMIN``. That's possible by injecting
-the :class:`Symfony\\Bundle\\SecurityBundle\\Security`
-into your voter. You can use this to, for example, *always* allow access to a user
+to see if the current user has ``ROLE_SUPER_ADMIN``. That's possible by using an
+:class:`access decision manager <Symfony\\Component\\Security\\Core\\Authorization\\AccessDecisionManagerInterface>`
+inside your voter. You can use this to, for example, *always* allow access to a user
 with ``ROLE_SUPER_ADMIN``::
 
     // src/Security/PostVoter.php
 
     // ...
-    use Symfony\Bundle\SecurityBundle\Security;
+    use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
 
     class PostVoter extends Voter
     {
         // ...
 
         public function __construct(
-            private Security $security,
+            private AccessDecisionManagerInterface $accessDecisionManager,
         ) {
         }
 
@@ -261,7 +261,7 @@ with ``ROLE_SUPER_ADMIN``::
             // ...
 
             // ROLE_SUPER_ADMIN can do anything! The power!
-            if ($this->security->isGranted('ROLE_SUPER_ADMIN')) {
+            if ($this->accessDecisionManager->decide($token, ['ROLE_SUPER_ADMIN'])) {
                 return true;
             }
 
@@ -269,6 +269,25 @@ with ``ROLE_SUPER_ADMIN``::
         }
     }
 
+.. warning::
+
+    In the previous example, avoid using the following code to check if a role
+    is granted permission::
+
+        // DON'T DO THIS
+        use Symfony\Component\Security\Core\Security;
+        // ...
+
+        if ($this->security->isGranted('ROLE_SUPER_ADMIN')) {
+            // ...
+        }
+
+    The ``Security::isGranted()`` method inside a voter has a significant
+    drawback: it does not guarantee that the checks are performed on the same
+    token as the one in your voter. The token in the token storage might have
+    changed or could change in the meantime. Always use the ``AccessDecisionManager``
+    instead.
+
 If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`,
 you're done! Symfony will automatically pass the ``security.helper``
 service when instantiating your voter (thanks to autowiring).
diff --git a/serializer.rst b/serializer.rst
index 91fd92a39a3..d541310aa15 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -1,10 +1,17 @@
 How to Use the Serializer
 =========================
 
-Symfony provides a serializer to serialize/deserialize to and from objects and
-different formats (e.g. JSON or XML). Before using it, read the
-:doc:`Serializer component docs </components/serializer>` to get familiar with
-its philosophy and the normalizers and encoders terminology.
+Symfony provides a serializer to transform data structures from one format
+to PHP objects and the other way around.
+
+This is most commonly used when building an API or communicating with third
+party APIs. The serializer can transform an incoming JSON request payload
+to a PHP object that is consumed by your application. Then, when generating
+the response, you can use the serializer to transform the PHP objects back
+to a JSON response.
+
+It can also be used to for instance load CSV configuration data as PHP
+objects, or even to transform between formats (e.g. YAML to XML).
 
 .. _activating_the_serializer:
 
@@ -12,424 +19,446 @@ Installation
 ------------
 
 In applications using :ref:`Symfony Flex <symfony-flex>`, run this command to
-install the ``serializer`` :ref:`Symfony pack <symfony-packs>` before using it:
+install the serializer :ref:`Symfony pack <symfony-packs>` before using it:
 
 .. code-block:: terminal
 
     $ composer require symfony/serializer-pack
 
-Using the Serializer Service
-----------------------------
+.. note::
+
+    The serializer pack also installs some commonly used optional
+    dependencies of the Serializer component. When using this component
+    outside the Symfony framework, you might want to start with the
+    ``symfony/serializer`` package and install optional dependencies if you
+    need them.
 
-Once enabled, the serializer service can be injected in any service where
-you need it or it can be used in a controller::
+.. seealso::
 
-    // src/Controller/DefaultController.php
-    namespace App\Controller;
+    A popular alternative to the Symfony Serializer component is the third-party
+    library, `JMS serializer`_.
 
-    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
-    use Symfony\Component\HttpFoundation\Response;
-    use Symfony\Component\Serializer\SerializerInterface;
+Serializing an Object
+---------------------
 
-    class DefaultController extends AbstractController
+For this example, assume the following class exists in your project::
+
+    // src/Model/Person.php
+    namespace App\Model;
+
+    class Person
     {
-        public function index(SerializerInterface $serializer): Response
+        public function __construct(
+            private int $age,
+            private string $name,
+            private bool $sportsperson
+        ) {
+        }
+
+        public function getAge(): int
+        {
+            return $this->age;
+        }
+
+        public function getName(): string
+        {
+            return $this->name;
+        }
+
+        public function isSportsperson(): bool
         {
-            // keep reading for usage examples
+            return $this->sportsperson;
         }
     }
 
-Or you can use the ``serialize`` Twig filter in a template:
+If you want to transform objects of this type into a JSON structure (e.g.
+to send them via an API response), get the ``serializer`` service by using
+the :class:`Symfony\\Component\\Serializer\\SerializerInterface` parameter type:
 
-.. code-block:: twig
+.. configuration-block::
 
-    {{ object|serialize(format = 'json') }}
+    .. code-block:: php-symfony
 
-See the :doc:`twig reference </reference/twig_reference>` for
-more information.
+        // src/Controller/PersonController.php
+        namespace App\Controller;
 
-Adding Normalizers and Encoders
--------------------------------
+        use App\Model\Person;
+        use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+        use Symfony\Component\HttpFoundation\JsonResponse;
+        use Symfony\Component\HttpFoundation\Response;
+        use Symfony\Component\Serializer\SerializerInterface;
 
-Once enabled, the ``serializer`` service will be available in the container.
-It comes with a set of useful :ref:`encoders <component-serializer-encoders>`
-and :ref:`normalizers <component-serializer-normalizers>`.
-
-Encoders supporting the following formats are enabled:
-
-* JSON: :class:`Symfony\\Component\\Serializer\\Encoder\\JsonEncoder`
-* XML: :class:`Symfony\\Component\\Serializer\\Encoder\\XmlEncoder`
-* CSV: :class:`Symfony\\Component\\Serializer\\Encoder\\CsvEncoder`
-* YAML: :class:`Symfony\\Component\\Serializer\\Encoder\\YamlEncoder`
-
-As well as the following normalizers:
-
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer`
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeNormalizer`
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeZoneNormalizer`
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\DateIntervalNormalizer`
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\FormErrorNormalizer`
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\DataUriNormalizer`
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\JsonSerializableNormalizer`
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\ArrayDenormalizer`
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\ConstraintViolationListNormalizer`
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\ProblemNormalizer`
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\BackedEnumNormalizer`
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\TranslatableNormalizer`
-
-Other :ref:`built-in normalizers <component-serializer-normalizers>` and
-custom normalizers and/or encoders can also be loaded by tagging them as
-:ref:`serializer.normalizer <reference-dic-tags-serializer-normalizer>` and
-:ref:`serializer.encoder <reference-dic-tags-serializer-encoder>`. It's also
-possible to set the priority of the tag in order to decide the matching order.
+        class PersonController extends AbstractController
+        {
+            public function index(SerializerInterface $serializer): Response
+            {
+                $person = new Person('Jane Doe', 39, false);
 
-.. danger::
+                $jsonContent = $serializer->serialize($person, 'json');
+                // $jsonContent contains {"name":"Jane Doe","age":39,"sportsperson":false}
 
-    Always make sure to load the ``DateTimeNormalizer`` when serializing the
-    ``DateTime`` or ``DateTimeImmutable`` classes to avoid excessive memory
-    usage and exposing internal details.
+                return JsonResponse::fromJsonString($jsonContent);
+            }
+        }
 
-.. _serializer_serializer-context:
+    .. code-block:: php-standalone
 
-Serializer Context
-------------------
+        use App\Model\Person;
+        use Symfony\Component\Serializer\Encoder\JsonEncoder;
+        use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
+        use Symfony\Component\Serializer\Serializer;
 
-The serializer can define a context to control the (de)serialization of
-resources. This context is passed to all normalizers. For example:
+        $encoders = [new JsonEncoder()];
+        $normalizers = [new ObjectNormalizer()];
+        $serializer = new Serializer($normalizers, $encoders);
 
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeNormalizer` uses
-  ``datetime_format`` key as date time format;
-* :class:`Symfony\\Component\\Serializer\\Normalizer\\AbstractObjectNormalizer`
-  uses ``preserve_empty_objects`` to represent empty objects as ``{}`` instead
-  of ``[]`` in JSON.
-* :class:`Symfony\\Component\\Serializer\\Serializer`
-  uses ``empty_array_as_object`` to represent empty arrays as ``{}`` instead
-  of ``[]`` in JSON.
+        $person = new Person('Jane Done', 39, false);
 
-You can pass the context as follows::
+        $jsonContent = $serializer->serialize($person, 'json');
+        // $jsonContent contains {"name":"Jane Doe","age":39,"sportsperson":false}
 
-    $serializer->serialize($something, 'json', [
-        DateTimeNormalizer::FORMAT_KEY => 'Y-m-d H:i:s',
-    ]);
+The first parameter of the :method:`Symfony\\Component\\Serializer\\Serializer::serialize`
+is the object to be serialized and the second is used to choose the proper
+encoder (i.e. format), in this case the :class:`Symfony\\Component\\Serializer\\Encoder\\JsonEncoder`.
 
-    $serializer->deserialize($someJson, Something::class, 'json', [
-        DateTimeNormalizer::FORMAT_KEY => 'Y-m-d H:i:s',
-    ]);
+.. tip::
 
-You can also configure the default context through the framework
-configuration:
+    When your controller class extends ``AbstractController`` (like in the
+    example above), you can simplify your controller by using the
+    :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController::json`
+    method to create a JSON response from an object using the Serializer::
 
-.. configuration-block::
+        class PersonController extends AbstractController
+        {
+            public function index(): Response
+            {
+                $person = new Person('Jane Doe', 39, false);
 
-    .. code-block:: yaml
+                // when the Serializer is not available, this will use json_encode()
+                return $this->json($person);
+            }
+        }
 
-        # config/packages/framework.yaml
-        framework:
-            # ...
-            serializer:
-                default_context:
-                    enable_max_depth: true
-                    yaml_indentation: 2
+Using the Serializer in Twig Templates
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-    .. code-block:: xml
+You can also serialize objects in any Twig template using the ``serialize``
+filter:
 
-        <!-- config/packages/framework.xml -->
-        <framework:config>
-            <!-- ... -->
-            <framework:serializer>
-                <default-context enable-max-depth="true" yaml-indentation="2"/>
-            </framework:serializer>
-        </framework:config>
+.. code-block:: twig
 
-    .. code-block:: php
+    {{ person|serialize(format = 'json') }}
 
-        // config/packages/framework.php
-        use Symfony\Component\Serializer\Encoder\YamlEncoder;
-        use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
-        use Symfony\Config\FrameworkConfig;
+See the :ref:`twig reference <reference-twig-filter-serialize>` for more
+information.
 
-        return static function (FrameworkConfig $framework): void {
-            $framework->serializer()
-                ->defaultContext([
-                    AbstractObjectNormalizer::ENABLE_MAX_DEPTH => true,
-                    YamlEncoder::YAML_INDENTATION => 2,
-                ])
-            ;
-        };
+Deserializing an Object
+-----------------------
 
-You can also specify the context on a per-property basis::
+APIs often also need to convert a formatted request body (e.g. JSON) to a
+PHP object. This process is called *deserialization* (also known as "hydration"):
 
 .. configuration-block::
 
-    .. code-block:: php-attributes
+    .. code-block:: php-symfony
 
-        namespace App\Model;
+        // src/Controller/PersonController.php
+        namespace App\Controller;
 
-        use Symfony\Component\Serializer\Annotation\Context;
-        use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
+        // ...
+        use Symfony\Component\HttpFoundation\Exception\BadRequestException;
+        use Symfony\Component\HttpFoundation\Request;
 
-        class Person
+        class PersonController extends AbstractController
         {
-            #[Context([DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'])]
-            public \DateTimeInterface $createdAt;
-
             // ...
+
+            public function create(Request $request, SerializerInterface $serializer): Response
+            {
+                if ('json' !== $request->getContentTypeFormat()) {
+                    throw new BadRequestException('Unsupported content format');
+                }
+
+                $jsonData = $request->getContent();
+                $person = $serializer->deserialize($jsonData, Person::class, 'json');
+
+                // ... do something with $person and return a response
+            }
         }
 
-    .. code-block:: yaml
+    .. code-block:: php-standalone
 
-        # config/serializer/custom_config.yaml
-        App\Model\Person:
-            attributes:
-                createdAt:
-                    contexts:
-                        - { context: { datetime_format: 'Y-m-d' } }
+        use App\Model\Person;
+        use Symfony\Component\Serializer\Encoder\JsonEncoder;
+        use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
+        use Symfony\Component\Serializer\Serializer;
 
-    .. code-block:: xml
+        // ...
+        $jsonData = ...; // fetch JSON from the request
+        $person = $serializer->deserialize($jsonData, Person::class, 'json');
 
-        <!-- config/serializer/custom_config.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
-                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
-        >
-            <class name="App\Model\Person">
-                <attribute name="createdAt">
-                    <context>
-                        <entry name="datetime_format">Y-m-d</entry>
-                    </context>
-                </attribute>
-            </class>
-        </serializer>
+In this case, :method:`Symfony\\Component\\Serializer\\Serializer::deserialize`
+needs three parameters:
 
-Use the options to specify context specific to normalization or denormalization::
+#. The data to be decoded
+#. The name of the class this information will be decoded to
+#. The name of the encoder used to convert the data to an array (i.e. the
+   input format)
 
-    namespace App\Model;
+When sending a request to this controller (e.g.
+``{"first_name":"John Doe","age":54,"sportsperson":true}``), the serializer
+will create a new instance of ``Person`` and sets the properties to the
+values from the given JSON.
 
-    use Symfony\Component\Serializer\Annotation\Context;
-    use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
+.. note::
 
-    class Person
-    {
-        #[Context(
-            normalizationContext: [DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'],
-            denormalizationContext: [DateTimeNormalizer::FORMAT_KEY => '!Y-m-d'], // To prevent to have the time from the moment of denormalization
-        )]
-        public \DateTimeInterface $createdAt;
+    By default, additional attributes that are not mapped to the
+    denormalized object will be ignored by the Serializer component. For
+    instance, if a request to the above controller contains ``{..., "city": "Paris"}``,
+    the ``city`` field will be ignored. You can also throw an exception in
+    these cases using the :ref:`serializer context <serializer-context>`
+    you'll learn about later.
 
-        // ...
-    }
+.. seealso::
 
-You can also restrict the usage of a context to some groups::
+    You can also deserialize data into an existing object instance (e.g.
+    when updating data). See :ref:`Deserializing in an Existing Object <serializer-populate-existing-object>`.
 
-    namespace App\Model;
+.. _serializer-process:
 
-    use Symfony\Component\Serializer\Annotation\Context;
-    use Symfony\Component\Serializer\Annotation\Groups;
-    use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
+The Serialization Process: Normalizers and Encoders
+---------------------------------------------------
 
-    class Person
-    {
-        #[Groups(['extended'])]
-        #[Context([DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339])]
-        #[Context(
-            context: [DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339_EXTENDED],
-            groups: ['extended'],
-        )]
-        public \DateTimeInterface $createdAt;
+The serializer uses a two-step process when (de)serializing objects:
 
-        // ...
-    }
+.. raw:: html
 
-The attribute can be repeated as much as needed on a single property.
-Context without group is always applied first. Then context for the matching
-groups are merged in the provided order.
+    <object data="_images/serializer/serializer_workflow.svg" type="image/svg+xml"
+        alt="A flow diagram showing how objects are serialized/deserialized. This is described in the subsequent paragraph."
+    ></object>
 
-If you repeat the same context in multiple properties, consider using the
-``#[Context]`` attribute on your class to apply that context configuration to
-all the properties of the class::
+In both directions, data is always first converted to an array. This splits
+the process in two separate responsibilities:
 
-    namespace App\Model;
+Normalizers
+    These classes convert **objects** into **arrays** and vice versa. They
+    do the heavy lifting of finding out which class properties to
+    serialize, what value they hold and what name they should have.
+Encoders
+    Encoders convert **arrays** into a specific **format** and the other
+    way around. Each encoder knows exactly how to parse and generate a
+    specific format, for instance JSON or XML.
 
-    use Symfony\Component\Serializer\Annotation\Context;
-    use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
+Internally, the ``Serializer`` class uses a sorted list of normalizers and
+one encoder for the specific format when (de)serializing an object.
 
-    #[Context([DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339])]
-    #[Context(
-        context: [DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339_EXTENDED],
-        groups: ['extended'],
-    )]
-    class Person
-    {
-        // ...
-    }
+There are several normalizers configured in the default ``serializer``
+service. The most important normalizer is the
+:class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer`. This
+normalizer uses reflection and the :doc:`PropertyAccess component </components/property_access>`
+to transform between any object and an array. You'll learn more about
+:ref:`this and other normalizers <serializer-normalizers>` later.
 
-.. _serializer-using-context-builders:
+The default serializer is also configured with some encoders, covering the
+common formats used by HTTP applications:
 
-Using Context Builders
-----------------------
+* :class:`Symfony\\Component\\Serializer\\Encoder\\JsonEncoder`
+* :class:`Symfony\\Component\\Serializer\\Encoder\\XmlEncoder`
+* :class:`Symfony\\Component\\Serializer\\Encoder\\CsvEncoder`
+* :class:`Symfony\\Component\\Serializer\\Encoder\\YamlEncoder`
 
-To define the (de)serialization context, you can use "context builders", which
-are objects that help you to create that context by providing autocompletion,
-validation, and documentation::
+Read more about these encoders and their configuration in
+:doc:`/serializer/encoders`.
 
-    use Symfony\Component\Serializer\Context\Normalizer\DateTimeNormalizerContextBuilder;
+.. tip::
 
-    $contextBuilder = (new DateTimeNormalizerContextBuilder())->withFormat('Y-m-d H:i:s');
-    $serializer->serialize($something, 'json', $contextBuilder->toArray());
+    The `API Platform`_ project provides encoders for more advanced
+    formats:
 
-Each normalizer/encoder has its related :ref:`context builder <component-serializer-context-builders>`.
-To create a more complex (de)serialization context, you can chain them using the
-``withContext()`` method::
+    * `JSON-LD`_ along with the `Hydra Core Vocabulary`_
+    * `OpenAPI`_ v2 (formerly Swagger) and v3
+    * `GraphQL`_
+    * `JSON:API`_
+    * `HAL`_
 
-    use Symfony\Component\Serializer\Context\Encoder\CsvEncoderContextBuilder;
-    use Symfony\Component\Serializer\Context\Normalizer\ObjectNormalizerContextBuilder;
+.. _serializer-context:
 
-    $initialContext = [
-        'custom_key' => 'custom_value',
-    ];
+Serializer Context
+~~~~~~~~~~~~~~~~~~
 
-    $contextBuilder = (new ObjectNormalizerContextBuilder())
-        ->withContext($initialContext)
-        ->withGroups(['group1', 'group2']);
+The serializer, and its normalizers and encoders, are configured through
+the *serializer context*. This context can be configured in multiple
+places:
 
-    $contextBuilder = (new CsvEncoderContextBuilder())
-        ->withContext($contextBuilder)
-        ->withDelimiter(';');
+* :ref:`Globally through the framework configuration <serializer-default-context>`
+* :ref:`While serializing/deserializing <serializer-context-while-serializing-deserializing>`
+* :ref:`For a specific property <serializer-using-context-builders>`
 
-    $serializer->serialize($something, 'csv', $contextBuilder->toArray());
+You can use all three options at the same time. When the same setting is
+configured in multiple places, the latter in the list above will override
+the previous one (e.g. the setting on a specific property overrides the one
+configured globally).
+
+.. _serializer-default-context:
+
+Configure a Default Context
+...........................
+
+You can configure a default context in the framework configuration, for
+instance to disallow extra fields while deserializing:
 
-You can also :doc:`create your context builders </serializer/custom_context_builders>`
-to have autocompletion, validation, and documentation for your custom context values.
+.. configuration-block::
+
+    .. code-block:: yaml
 
-.. _serializer-using-serialization-groups-attributes:
+        # config/packages/serializer.yaml
+        framework:
+            serializer:
+                default_context:
+                    allow_extra_attributes: false
 
-Using Serialization Groups Attributes
--------------------------------------
+    .. code-block:: xml
 
-You can add :ref:`#[Groups] attributes <component-serializer-attributes-groups-attributes>`
-to your class properties::
+        <!-- config/packages/serializer.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <framework:config>
+                <framework:serializer>
+                    <framework:default-context>
+                        <framework:allow-extra-attributes>false</framework:allow-extra-attributes>
+                    </framework:default-context>
+                </framework:serializer>
+            </framework:config>
+        </container>
 
-    // src/Entity/Product.php
-    namespace App\Entity;
+    .. code-block:: php
 
-    use Doctrine\ORM\Mapping as ORM;
-    use Symfony\Component\Serializer\Annotation\Groups;
+        // config/packages/serializer.php
+        use Symfony\Config\FrameworkConfig;
 
-    #[ORM\Entity]
-    class Product
-    {
-        #[ORM\Id]
-        #[ORM\GeneratedValue]
-        #[ORM\Column(type: 'integer')]
-        #[Groups(['show_product', 'list_product'])]
-        private int $id;
+        return static function (FrameworkConfig $framework): void {
+            $framework->serializer()
+                ->defaultContext('', [
+                    'allow_extra_attributes' => false,
+                ])
+            ;
+        };
 
-        #[ORM\Column(type: 'string', length: 255)]
-        #[Groups(['show_product', 'list_product'])]
-        private string $name;
+    .. code-block:: php-standalone
 
-        #[ORM\Column(type: 'text')]
-        #[Groups(['show_product'])]
-        private string $description;
-    }
+        use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
+        use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
 
-You can also use the ``#[Groups]`` attribute on class level::
+        // ...
+        $normalizers = [
+            new ObjectNormalizer(null, null, null, null, null, null, [
+                'allow_extra_attributes' => false,
+            ]),
+        ];
+        $serializer = new Serializer($normalizers, $encoders);
 
-    #[ORM\Entity]
-    #[Groups(['show_product'])]
-    class Product
-    {
-        #[ORM\Id]
-        #[ORM\GeneratedValue]
-        #[ORM\Column(type: 'integer')]
-        #[Groups(['list_product'])]
-        private int $id;
+.. _serializer-context-while-serializing-deserializing:
 
-        #[ORM\Column(type: 'string', length: 255)]
-        #[Groups(['list_product'])]
-        private string $name;
+Pass Context while Serializing/Deserializing
+............................................
 
-        #[ORM\Column(type: 'text')]
-        private string $description;
-    }
+You can also configure the context for a single call to
+``serialize()``/``deserialize()``. For instance, you can skip
+properties with a ``null`` value only for one serialize call::
 
-In this example, the ``id`` and the ``name`` properties belong to the
-``show_product`` and ``list_product`` groups. The ``description`` property
-only belongs to the ``show_product`` group.
+    use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
 
-Now that your groups are defined, you can choose which groups to use when
-serializing::
+    // ...
+    $serializer->serialize($person, 'json', [
+        AbstractObjectNormalizer::SKIP_NULL_VALUES => true
+    ]);
 
-    use Symfony\Component\Serializer\Context\Normalizer\ObjectNormalizerContextBuilder;
+    // next calls to serialize() will NOT skip null values
 
-    $context = (new ObjectNormalizerContextBuilder())
-        ->withGroups('show_product')
-        ->toArray();
+.. _serializer-using-context-builders:
 
-    $json = $serializer->serialize($product, 'json', $context);
+Using Context Builders
+""""""""""""""""""""""
 
-.. tip::
+You can use "context builders" to help define the (de)serialization
+context. Context builders are PHP objects that provide autocompletion,
+validation, and documentation of context options::
 
-    The value of the ``groups`` key can be a single string, or an array of strings.
+    use Symfony\Component\Serializer\Context\Normalizer\DateTimeNormalizerContextBuilder;
 
-In addition to the ``#[Groups]`` attribute, the Serializer component also
-supports YAML or XML files. These files are automatically loaded when being
-stored in one of the following locations:
+    $contextBuilder = (new DateTimeNormalizerContextBuilder())
+        ->withFormat('Y-m-d H:i:s');
+    $serializer->serialize($something, 'json', $contextBuilder->toArray());
 
-* All ``*.yaml`` and ``*.xml`` files in the ``config/serializer/``
-  directory.
-* The ``serialization.yaml`` or ``serialization.xml`` file in
-  the ``Resources/config/`` directory of a bundle;
-* All ``*.yaml`` and ``*.xml`` files in the ``Resources/config/serialization/``
-  directory of a bundle.
+Each normalizer/encoder has its related context builder. To create a more
+complex (de)serialization context, you can chain them using the
+``withContext()`` method::
 
-.. note::
+    use Symfony\Component\Serializer\Context\Encoder\CsvEncoderContextBuilder;
+    use Symfony\Component\Serializer\Context\Normalizer\ObjectNormalizerContextBuilder;
 
-    The groups used by default when normalizing and denormalizing objects are
-    ``Default`` and the group that matches the class name. For example, if you
-    are normalizing a ``App\Entity\Product`` object, the groups used are
-    ``Default`` and ``Product``.
+    $initialContext = [
+        'custom_key' => 'custom_value',
+    ];
 
-    .. versionadded:: 7.1
+    $contextBuilder = (new ObjectNormalizerContextBuilder())
+        ->withContext($initialContext)
+        ->withGroups(['group1', 'group2']);
+
+    $contextBuilder = (new CsvEncoderContextBuilder())
+        ->withContext($contextBuilder)
+        ->withDelimiter(';');
 
-        The default use of the class name and ``Default`` groups when normalizing
-        and denormalizing objects was introduced in Symfony 7.1.
+    $serializer->serialize($something, 'csv', $contextBuilder->toArray());
 
-.. _serializer-enabling-metadata-cache:
+.. seealso::
 
-Using Nested Attributes
------------------------
+    You can also :doc:`create your context builders </serializer/custom_context_builders>`
+    to have autocompletion, validation, and documentation for your custom
+    context values.
 
-To map nested properties, use the ``SerializedPath`` configuration to define
-their paths using a :doc:`valid PropertyAccess syntax </components/property_access>`:
+Configure Context on a Specific Property
+........................................
+
+At last, you can also configure context values on a specific object
+property. For instance, to configure the datetime format:
 
 .. configuration-block::
 
     .. code-block:: php-attributes
 
-        namespace App\Model;
+        // src/Model/Person.php
 
-        use Symfony\Component\Serializer\Attribute\SerializedPath;
+        // ...
+        use Symfony\Component\Serializer\Attribute\Context;
+        use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
 
         class Person
         {
-            #[SerializedPath('[profile][information][birthday]')]
-            private string $birthday;
+            #[Context([DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'])]
+            public \DateTimeImmutable $createdAt;
 
             // ...
         }
 
     .. code-block:: yaml
 
+        # config/serializer/person.yaml
         App\Model\Person:
             attributes:
-                dob:
-                    serialized_path: '[profile][information][birthday]'
+                createdAt:
+                    contexts:
+                        - context: { datetime_format: 'Y-m-d' }
 
     .. code-block:: xml
 
+        <!-- config/serializer/person.xml -->
         <?xml version="1.0" encoding="UTF-8" ?>
         <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -437,96 +466,1034 @@ their paths using a :doc:`valid PropertyAccess syntax </components/property_acce
                 https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
         >
             <class name="App\Model\Person">
-                <attribute name="dob" serialized-path="[profile][information][birthday]"/>
+                <attribute name="createdAt">
+                    <context>
+                        <entry name="datetime_format">Y-m-d</entry>
+                    </context>
+                </attribute>
             </class>
         </serializer>
 
-Using the configuration from above, denormalizing with a metadata-aware
-normalizer will write the ``birthday`` field from ``$data`` onto the ``Person``
-object::
+.. note::
 
-    $data = [
-        'profile' => [
-            'information' => [
-                'birthday' => '01-01-1970',
-            ],
-        ],
-    ];
-    $person = $normalizer->denormalize($data, Person::class, 'any');
-    $person->getBirthday(); // 01-01-1970
+    When using YAML or XML, the mapping files must be placed in one of
+    these locations:
 
-When using attributes, the ``SerializedPath`` can either
-be set on the property or the associated _getter_ method. The ``SerializedPath``
-cannot be used in combination with a ``SerializedName`` for the same property.
+    * All ``*.yaml`` and ``*.xml`` files in the ``config/serializer/``
+      directory.
+    * The ``serialization.yaml`` or ``serialization.xml`` file in the
+      ``Resources/config/`` directory of a bundle;
+    * All ``*.yaml`` and ``*.xml`` files in the ``Resources/config/serialization/``
+      directory of a bundle.
 
-Configuring the Metadata Cache
-------------------------------
+You can also specify a context specific to normalization or denormalization:
 
-The metadata for the serializer is automatically cached to enhance application
-performance. By default, the serializer uses the ``cache.system`` cache pool
-which is configured using the :ref:`cache.system <reference-cache-system>`
-option.
+.. configuration-block::
+
+    .. code-block:: php-attributes
 
-Enabling a Name Converter
--------------------------
+        // src/Model/Person.php
 
-The use of a :ref:`name converter <component-serializer-converting-property-names-when-serializing-and-deserializing>`
-service can be defined in the configuration using the :ref:`name_converter <reference-serializer-name_converter>`
-option.
+        // ...
+        use Symfony\Component\Serializer\Attribute\Context;
+        use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
 
-The built-in :ref:`CamelCase to snake_case name converter <using-camelized-method-names-for-underscored-attributes>`
-can be enabled by using the ``serializer.name_converter.camel_case_to_snake_case``
-value:
+        class Person
+        {
+            #[Context(
+                normalizationContext: [DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'],
+                denormalizationContext: [DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339],
+            )]
+            public \DateTimeImmutable $createdAt;
 
-.. configuration-block::
+            // ...
+        }
 
     .. code-block:: yaml
 
-        # config/packages/framework.yaml
-        framework:
-            # ...
-            serializer:
-                name_converter: 'serializer.name_converter.camel_case_to_snake_case'
+        # config/serializer/person.yaml
+        App\Model\Person:
+            attributes:
+                createdAt:
+                    contexts:
+                        - normalizationContext: { datetime_format: 'Y-m-d' }
+                          denormalizationContext: { datetime_format: !php/const \DateTime::RFC3339 }
 
     .. code-block:: xml
 
-        <!-- config/packages/framework.xml -->
-        <framework:config>
-            <!-- ... -->
-            <framework:serializer name-converter="serializer.name_converter.camel_case_to_snake_case"/>
-        </framework:config>
+        <!-- config/serializer/person.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
+                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
+        >
+            <class name="App\Model\Person">
+                <attribute name="createdAt">
+                    <normalization-context>
+                        <entry name="datetime_format">Y-m-d</entry>
+                    </normalization-context>
 
-    .. code-block:: php
+                    <denormalization-context>
+                        <entry name="datetime_format">Y-m-d\TH:i:sP</entry>
+                    </denormalization-context>
+                </attribute>
+            </class>
+        </serializer>
 
-        // config/packages/framework.php
-        use Symfony\Config\FrameworkConfig;
+.. _serializer-context-group:
 
-        return static function (FrameworkConfig $framework): void {
-            $framework->serializer()->nameConverter('serializer.name_converter.camel_case_to_snake_case');
-        };
+You can also restrict the usage of a context to some
+:ref:`groups <serializer-groups-attribute>`:
 
-Debugging the Serializer
-------------------------
+.. configuration-block::
 
-Use the ``debug:serializer`` command to dump the serializer metadata of a
-given class:
+    .. code-block:: php-attributes
 
-.. code-block:: terminal
+        // src/Model/Person.php
 
-    $ php bin/console debug:serializer 'App\Entity\Book'
+        // ...
+        use Symfony\Component\Serializer\Attribute\Context;
+        use Symfony\Component\Serializer\Attribute\Groups;
+        use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
 
-        App\Entity\Book
-        ---------------
+        class Person
+        {
+            #[Groups(['extended'])]
+            #[Context([DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339])]
+            #[Context(
+                context: [DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339_EXTENDED],
+                groups: ['extended'],
+            )]
+            public \DateTimeImmutable $createdAt;
 
-        +----------+------------------------------------------------------------+
-        | Property | Options                                                    |
-        +----------+------------------------------------------------------------+
-        | name     | [                                                          |
-        |          |   "groups" => [                                            |
-        |          |       "book:read",                                         |
-        |          |       "book:write",                                        |
-        |          |   ],                                                       |
-        |          |   "maxDepth" => 1,                                         |
+            // ...
+        }
+
+    .. code-block:: yaml
+
+        # config/serializer/person.yaml
+        App\Model\Person:
+            attributes:
+                createdAt:
+                    groups: [extended]
+                    contexts:
+                        - context: { datetime_format: !php/const \DateTime::RFC3339 }
+                        - context: { datetime_format: !php/const \DateTime::RFC3339_EXTENDED }
+                          groups: [extended]
+
+    .. code-block:: xml
+
+        <!-- config/serializer/person.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
+                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
+        >
+            <class name="App\Model\Person">
+                <attribute name="createdAt">
+                    <group>extended</group>
+
+                    <context>
+                        <entry name="datetime_format">Y-m-d\TH:i:sP</entry>
+                    </context>
+                    <context>
+                        <entry name="datetime_format">Y-m-d\TH:i:s.vP</entry>
+                        <group>extended</group>
+                    </context>
+                </attribute>
+            </class>
+        </serializer>
+
+The attribute can be repeated as much as needed on a single property.
+Context without group is always applied first. Then context for the
+matching groups are merged in the provided order.
+
+If you repeat the same context in multiple properties, consider using the
+``#[Context]`` attribute on your class to apply that context configuration to
+all the properties of the class::
+
+    namespace App\Model;
+
+    use Symfony\Component\Serializer\Attribute\Context;
+    use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
+
+    #[Context([DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339])]
+    #[Context(
+        context: [DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339_EXTENDED],
+        groups: ['extended'],
+    )]
+    class Person
+    {
+        // ...
+    }
+
+Serializing to or from PHP Arrays
+---------------------------------
+
+The default :class:`Symfony\\Component\\Serializer\\Serializer` can also be
+used to only perform one step of the :ref:`two step serialization process <serializer-process>`
+by using the respective interface:
+
+.. configuration-block::
+
+    .. code-block:: php-symfony
+
+        use Symfony\Component\Serializer\Encoder\DecoderInterface;
+        use Symfony\Component\Serializer\Encoder\EncoderInterface;
+        use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
+        use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+        // ...
+
+        class PersonController extends AbstractController
+        {
+            public function index(DenormalizerInterface&NormalizerInterface $serializer): Response
+            {
+                $person = new Person('Jane Doe', 39, false);
+
+                // use normalize() to convert a PHP object to an array
+                $personArray = $serializer->normalize($person, 'json');
+
+                // ...and denormalize() to convert an array back to a PHP object
+                $personCopy = $serializer->denormalize($personArray, Person::class);
+
+                // ...
+            }
+
+            public function json(DecoderInterface&EncoderInterface $serializer): Response
+            {
+                $data = ['name' => 'Jane Doe'];
+
+                // use encode() to transform PHP arrays into another format
+                $json = $serializer->encode($data, 'json');
+
+                // ...and decode() to transform any format to just PHP arrays (instead of objects)
+                $data = $serializer->decode('{"name":"Charlie Doe"}', 'json');
+                // $data contains ['name' => 'Charlie Doe']
+            }
+        }
+
+    .. code-block:: php-standalone
+
+        use App\Model\Person;
+        use Symfony\Component\Serializer\Encoder\JsonEncoder;
+        use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
+        use Symfony\Component\Serializer\Serializer;
+
+        $encoders = [new JsonEncoder()];
+        $normalizers = [new ObjectNormalizer()];
+        $serializer = new Serializer($normalizers, $encoders);
+
+        // use normalize() to convert a PHP object to an array
+        $personArray = $serializer->normalize($person, 'json');
+
+        // ...and denormalize() to convert an array back to a PHP object
+        $personCopy = $serializer->denormalize($personArray, Person::class);
+
+        $data = ['name' => 'Jane Doe'];
+
+        // use encode() to transform PHP arrays into another format
+        $json = $serializer->encode($data, 'json');
+
+        // ...and decode() to transform any format to just PHP arrays (instead of objects)
+        $data = $serializer->decode('{"name":"Charlie Doe"}', 'json');
+        // $data contains ['name' => 'Charlie Doe']
+
+.. _serializer_ignoring-attributes:
+
+Ignoring Properties
+-------------------
+
+The ``ObjectNormalizer`` normalizes *all* properties of an object and all
+methods starting with ``get*()``, ``has*()``, ``is*()`` and ``can*()``.
+Some properties or methods should never be serialized. You can exclude
+them using the ``#[Ignore]`` attribute:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Model/Person.php
+        namespace App\Model;
+
+        use Symfony\Component\Serializer\Attribute\Ignore;
+
+        class Person
+        {
+            // ...
+
+            #[Ignore]
+            public function isPotentiallySpamUser(): bool
+            {
+                // ...
+            }
+        }
+
+    .. code-block:: yaml
+
+        App\Model\Person:
+            attributes:
+                potentiallySpamUser:
+                    ignore: true
+
+    .. code-block:: xml
+
+        <?xml version="1.0" ?>
+        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
+                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
+        >
+            <class name="App\Model\Person">
+                <attribute name="potentiallySpamUser" ignore="true"/>
+            </class>
+        </serializer>
+
+The ``potentiallySpamUser`` property will now never be serialized:
+
+.. configuration-block::
+
+    .. code-block:: php-symfony
+
+        use App\Model\Person;
+
+        // ...
+        $person = new Person('Jane Doe', 32, false);
+        $json = $serializer->serialize($person, 'json');
+        // $json contains {"name":"Jane Doe","age":32,"sportsperson":false}
+
+        $person1 = $serializer->deserialize(
+            '{"name":"Jane Doe","age":32,"sportsperson":false","potentiallySpamUser":false}',
+            Person::class,
+            'json'
+        );
+        // the "potentiallySpamUser" value is ignored
+
+    .. code-block:: php-standalone
+
+        use App\Model\Person;
+        use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
+        use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader;
+        use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
+        use Symfony\Component\Serializer\Serializer;
+
+        // ...
+
+        // you need to pass a class metadata factory with a loader to the
+        // ObjectNormalizer when reading mapping information like Ignore or Groups.
+        // E.g. when using PHP attributes:
+        $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
+        $normalizers = [new ObjectNormalizer($classMetadataFactory)];
+
+        $serializer = new Serializer($normalizers, $encoders);
+
+        $person = new Person('Jane Doe', 32, false);
+        $json = $serializer->serialize($person, 'json');
+        // $json contains {"name":"Jane Doe","age":32,"sportsperson":false}
+
+        $person1 = $serializer->deserialize(
+            '{"name":"Jane Doe","age":32,"sportsperson":false","potentiallySpamUser":false}',
+            Person::class,
+            'json'
+        );
+        // the "potentiallySpamUser" value is ignored
+
+Ignoring Attributes Using the Context
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can also pass an array of attribute names to ignore at runtime using
+the ``ignored_attributes`` context options::
+
+    use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
+
+    // ...
+    $person = new Person('Jane Doe', 32, false);
+    $json = $serializer->serialize($person, 'json',
+    [
+        AbstractNormalizer::IGNORED_ATTRIBUTES => ['age'],
+    ]);
+    // $json contains {"name":"Jane Doe","sportsperson":false}
+
+However, this can quickly become unmaintainable if used excessively. See
+the next section about *serialization groups* for a better solution.
+
+.. _serializer-groups-attribute:
+
+Selecting Specific Properties
+-----------------------------
+
+Instead of excluding a property or method in all situations, you might need
+to exclude some properties in one place, but serialize them in another.
+Groups are a handy way to achieve this.
+
+You can add the ``#[Groups]`` attribute to your class:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Model/Person.php
+        namespace App\Model;
+
+        use Symfony\Component\Serializer\Attribute\Groups;
+
+        class Person
+        {
+            #[Groups(["admin-view"])]
+            private int $age;
+
+            #[Groups(["public-view"])]
+            private string $name;
+
+            #[Groups(["public-view"])]
+            private bool $sportsperson;
+
+            // ...
+        }
+
+    .. code-block:: yaml
+
+        # config/serializer/person.yaml
+        App\Model\Person:
+            attributes:
+                age:
+                    groups: ['admin-view']
+                name:
+                    groups: ['public-view']
+                sportsperson:
+                    groups: ['public-view']
+
+    .. code-block:: xml
+
+        <!-- config/serializer/person.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
+                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
+        >
+            <class name="App\Model\Person">
+                <attribute name="age">
+                    <group>admin-view</group>
+                </attribute>
+                <attribute name="name">
+                    <group>public-view</group>
+                </attribute>
+                <attribute name="sportsperson">
+                    <group>public-view</group>
+                </attribute>
+            </class>
+        </serializer>
+
+You can now choose which groups to use when serializing::
+
+    $json = $serializer->serialize(
+        $person,
+        'json',
+        ['groups' => 'public-view']
+    );
+    // $json contains {"name":"Jane Doe","sportsperson":false}
+
+    // you can also pass an array of groups
+    $json = $serializer->serialize(
+        $person,
+        'json',
+        ['groups' => ['public-view', 'admin-view']]
+    );
+    // $json contains {"name":"Jane Doe","age":32,"sportsperson":false}
+
+    // or use the special "*" value to select all groups
+    $json = $serializer->serialize(
+        $person,
+        'json',
+        ['groups' => '*']
+    );
+    // $json contains {"name":"Jane Doe","age":32,"sportsperson":false}
+
+Using the Serialization Context
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At last, you can also use the ``attributes`` context option to select
+properties at runtime::
+
+    use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
+    // ...
+
+    $json = $serializer->serialize($person, 'json', [
+        AbstractNormalizer::ATTRIBUTES => ['name', 'company' => ['name']]
+    ]);
+    // $json contains {"name":"Dunglas","company":{"name":"Les-Tilleuls.coop"}}
+
+Only attributes that are :ref:`not ignored <serializer_ignoring-attributes>`
+are available. If serialization groups are set, only attributes allowed by
+those groups can be used.
+
+.. _serializer-handling-arrays:
+
+Handling Arrays
+---------------
+
+The serializer is capable of handling arrays of objects. Serializing arrays
+works just like serializing a single object::
+
+    use App\Model\Person;
+
+    // ...
+    $person1 = new Person('Jane Doe', 39, false);
+    $person2 = new Person('John Smith', 52, true);
+
+    $persons = [$person1, $person2];
+    $JsonContent = $serializer->serialize($persons, 'json');
+
+    // $jsonContent contains [{"name":"Jane Doe","age":39,"sportsman":false},{"name":"John Smith","age":52,"sportsman":true}]
+
+To deserialize a list of objects, you have to append ``[]`` to the type
+parameter::
+
+    // ...
+
+    $jsonData = ...; // the serialized JSON data from the previous example
+    $persons = $serializer->deserialize($JsonData, Person::class.'[]', 'json');
+
+For nested classes, you have to add a PHPDoc type to the property, constructor or setter::
+
+    // src/Model/UserGroup.php
+    namespace App\Model;
+
+    class UserGroup
+    {
+        /**
+         * @param Person[] $members
+         */
+        public function __construct(
+            private array $members,
+        ) {
+        }
+
+        // or if you're using a setter
+
+        /**
+         * @param Person[] $members
+         */
+        public function setMembers(array $members): void
+        {
+            $this->members = $members;
+        }
+
+        // ...
+    }
+
+.. tip::
+
+    The Serializer also supports array types used in static analysis, like
+    ``list<Person>`` and ``array<Person>``. Make sure the
+    ``phpstan/phpdoc-parser`` and ``phpdocumentor/reflection-docblock``
+    packages are installed (these are part of the ``symfony/serializer-pack``).
+
+.. _serializer-nested-structures:
+
+Deserializing Nested Structures
+-------------------------------
+
+Some APIs might provide verbose nested structures that you want to flatten
+in the PHP object. For instance, imagine a JSON response like this:
+
+.. code-block:: json
+
+    {
+        "id": "123",
+        "profile": {
+            "username": "jdoe",
+            "personal_information": {
+                "full_name": "Jane Doe"
+            }
+        }
+    }
+
+You may wish to serialize this information to a single PHP object like::
+
+    class Person
+    {
+        private int $id;
+        private string $username;
+        private string $fullName;
+    }
+
+Use the ``#[SerializedPath]`` to specify the path of the nested property
+using :doc:`valid PropertyAccess syntax </components/property_access>`:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        namespace App\Model;
+
+        use Symfony\Component\Serializer\Attribute\SerializedPath;
+
+        class Person
+        {
+            private int $id;
+
+            #[SerializedPath('[profile][username]')]
+            private string $username;
+
+            #[SerializedPath('[profile][personal_information][full_name]')]
+            private string $fullName;
+        }
+
+    .. code-block:: yaml
+
+        App\Model\Person:
+            attributes:
+                username:
+                    serialized_path: '[profile][username]'
+                fullName:
+                    serialized_path: '[profile][personal_information][full_name]'
+
+    .. code-block:: xml
+
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
+                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
+        >
+            <class name="App\Model\Person">
+                <attribute name="username" serialized-path="[profile][username]"/>
+                <attribute name="fullName" serialized-path="[profile][personal_information][full_name]"/>
+            </class>
+        </serializer>
+
+.. warning::
+
+    The ``SerializedPath`` cannot be used in combination with a
+    ``SerializedName`` for the same property.
+
+The ``#[SerializedPath]`` attribute also applies to the serialization of a
+PHP object::
+
+    use App\Model\Person;
+    // ...
+
+    $person = new Person(123, 'jdoe', 'Jane Doe');
+    $jsonContent = $serializer->serialize($person, 'json');
+    // $jsonContent contains {"id":123,"profile":{"username":"jdoe","personal_information":{"full_name":"Jane Doe"}}}
+
+.. _serializer-name-conversion:
+
+Converting Property Names when Serializing and Deserializing
+------------------------------------------------------------
+
+Sometimes serialized attributes must be named differently than properties
+or getter/setter methods of PHP classes. This can be achieved using name
+converters.
+
+The serializer service uses the
+:class:`Symfony\\Component\\Serializer\\NameConverter\\MetadataAwareNameConverter`.
+With this name converter, you can change the name of an attribute using
+the ``#[SerializedName]`` attribute:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Model/Person.php
+        namespace App\Model;
+
+        use Symfony\Component\Serializer\Attribute\SerializedName;
+
+        class Person
+        {
+            #[SerializedName('customer_name')]
+            private string $name;
+
+            // ...
+        }
+
+    .. code-block:: yaml
+
+        # config/serializer/person.yaml
+        App\Entity\Person:
+            attributes:
+                name:
+                    serialized_name: customer_name
+
+    .. code-block:: xml
+
+        <!-- config/serializer/person.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
+                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
+        >
+            <class name="App\Entity\Person">
+                <attribute name="name" serialized-name="customer_name"/>
+            </class>
+        </serializer>
+
+This custom mapping is used to convert property names when serializing and
+deserializing objects:
+
+.. configuration-block::
+
+    .. code-block:: php-symfony
+
+        // ...
+
+        $json = $serializer->serialize($person, 'json');
+        // $json contains {"customer_name":"Jane Doe", ...}
+
+    .. code-block:: php-standalone
+
+        use App\Model\Person;
+        use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
+        use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader;
+        use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter;
+        use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
+        use Symfony\Component\Serializer\Serializer;
+
+        // ...
+
+        // Configure a loader to retrieve mapping information like SerializedName.
+        // E.g. when using PHP attributes:
+        $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
+        $nameConverter = new MetadataAwareNameConverter($classMetadataFactory);
+        $normalizers = [
+            new ObjectNormalizer($classMetadataFactory, $nameConverter),
+        ];
+
+        $serializer = new Serializer($normalizers, $encoders);
+
+        $person = new Person('Jane Doe', 32, false);
+        $json = $serializer->serialize($person, 'json');
+        // $json contains {"customer_name":"Jane Doe", ...}
+
+.. seealso::
+
+    You can also create a custom name converter class. Read more about this
+    in :doc:`/serializer/custom_name_converter`.
+
+.. _using-camelized-method-names-for-underscored-attributes:
+
+CamelCase to snake_case
+~~~~~~~~~~~~~~~~~~~~~~~
+
+In many formats, it's common to use underscores to separate words (also known
+as snake_case). However, in Symfony applications is common to use camelCase to
+name properties.
+
+Symfony provides a built-in name converter designed to transform between
+snake_case and CamelCased styles during serialization and deserialization
+processes. You can use it instead of the metadata aware name converter by
+setting the ``name_converter`` setting to
+``serializer.name_converter.camel_case_to_snake_case``:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/serializer.yaml
+        framework:
+            serializer:
+                name_converter: 'serializer.name_converter.camel_case_to_snake_case'
+
+    .. code-block:: xml
+
+        <!-- config/packages/serializer.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <framework:config>
+                <framework:serializer
+                    name-converter="serializer.name_converter.camel_case_to_snake_case"
+                />
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/serializer.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            $framework->serializer()
+                ->nameConverter('serializer.name_converter.camel_case_to_snake_case')
+            ;
+        };
+
+    .. code-block:: php-standalone
+
+        use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
+        use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
+
+        // ...
+        $normalizers = [
+            new ObjectNormalizer(null, new CamelCaseToSnakeCaseNameConverter()),
+        ];
+        $serializer = new Serializer($normalizers, $encoders);
+
+.. _serializer-built-in-normalizers:
+
+Serializer Normalizers
+----------------------
+
+By default, the serializer service is configured with the following
+normalizers (in order of priority):
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\UnwrappingDenormalizer`
+    Can be used to only denormalize a part of the input, read more about
+    this :ref:`later in this article <serializer-unwrapping-denormalizer>`.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\ProblemNormalizer`
+    Normalizes :class:`Symfony\\Component\\ErrorHandler\\Exception\\FlattenException`
+    errors according to the API Problem spec `RFC 7807`_.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\UidNormalizer`
+    Normalizes objects that extend :class:`Symfony\\Component\\Uid\\AbstractUid`.
+
+    The default normalization format for objects that implement :class:`Symfony\\Component\\Uid\\Uuid`
+    is the `RFC 4122`_ format (example: ``d9e7a184-5d5b-11ea-a62a-3499710062d0``).
+    The default normalization format for objects that implement :class:`Symfony\\Component\\Uid\\Ulid`
+    is the Base 32 format (example: ``01E439TP9XJZ9RPFH3T1PYBCR8``).
+    You can change the string format by setting the serializer context option
+    ``UidNormalizer::NORMALIZATION_FORMAT_KEY`` to ``UidNormalizer::NORMALIZATION_FORMAT_BASE_58``,
+    ``UidNormalizer::NORMALIZATION_FORMAT_BASE_32`` or ``UidNormalizer::NORMALIZATION_FORMAT_RFC_4122``.
+
+    Also it can denormalize ``uuid`` or ``ulid`` strings to :class:`Symfony\\Component\\Uid\\Uuid`
+    or :class:`Symfony\\Component\\Uid\\Ulid`. The format does not matter.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeNormalizer`
+    This normalizes between :phpclass:`DateTimeInterface` objects (e.g.
+    :phpclass:`DateTime` and :phpclass:`DateTimeImmutable`) and strings,
+    integers or floats.
+
+    :phpclass:`DateTime` and :phpclass:`DateTimeImmutable`) into strings,
+    integers or floats. By default, it converts them to strings using the
+    `RFC 3339`_ format. Use ``DateTimeNormalizer::FORMAT_KEY`` and
+    ``DateTimeNormalizer::TIMEZONE_KEY`` to change the format.
+
+    To convert the objects to integers or floats, set the serializer
+    context option ``DateTimeNormalizer::CAST_KEY`` to ``int`` or
+    ``float``.
+
+    .. versionadded:: 7.1
+
+        The ``DateTimeNormalizer::CAST_KEY`` context option was introduced in Symfony 7.1.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\ConstraintViolationListNormalizer`
+    This normalizer converts objects that implement
+    :class:`Symfony\\Component\\Validator\\ConstraintViolationListInterface`
+    into a list of errors according to the `RFC 7807`_ standard.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeZoneNormalizer`
+    This normalizer converts between :phpclass:`DateTimeZone` objects and strings that
+    represent the name of the timezone according to the `list of PHP timezones`_.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\DateIntervalNormalizer`
+    This normalizes between :phpclass:`DateInterval` objects and strings.
+    By default, the ``P%yY%mM%dDT%hH%iM%sS`` format is used. Use the
+    ``DateIntervalNormalizer::FORMAT_KEY`` option to change this.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\FormErrorNormalizer`
+    This normalizer works with classes that implement
+    :class:`Symfony\\Component\\Form\\FormInterface`.
+
+    It will get errors from the form and normalize them according to the
+    API Problem spec `RFC 7807`_.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\TranslatableNormalizer`
+    This normalizer converts objects implementing :class:`Symfony\\Contracts\\Translation\\TranslatableInterface`
+    to a translated string using the :doc:`translator </translation>`.
+
+    You can define the locale to use to translate the object by setting the
+    ``TranslatableNormalizer::NORMALIZATION_LOCALE_KEY`` context option.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\BackedEnumNormalizer`
+    This normalizer converts between :phpclass:`BackedEnum` enums and
+    strings or integers.
+
+    By default, an exception is thrown when data is not a valid backed enumeration. If you
+    want ``null`` instead, you can set the ``BackedEnumNormalizer::ALLOW_INVALID_VALUES`` option.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\DataUriNormalizer`
+    This normalizer converts between :phpclass:`SplFileInfo` objects and a
+    `data URI`_ string (``data:...``) such that files can be embedded into
+    serialized data.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\JsonSerializableNormalizer`
+    This normalizer works with classes that implement :phpclass:`JsonSerializable`.
+
+    It will call the :phpmethod:`JsonSerializable::jsonSerialize` method and
+    then further normalize the result. This means that nested
+    :phpclass:`JsonSerializable` classes will also be normalized.
+
+    This normalizer is particularly helpful when you want to gradually migrate
+    from an existing codebase using simple :phpfunction:`json_encode` to the Symfony
+    Serializer by allowing you to mix which normalizers are used for which classes.
+
+    Unlike with :phpfunction:`json_encode` circular references can be handled.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\ArrayDenormalizer`
+    This denormalizer converts an array of arrays to an array of objects
+    (with the given type). See :ref:`Handling Arrays <serializer-handling-arrays>`.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer`
+    This is the most powerful default normalizer and used for any object
+    that could not be normalized by the other normalizers.
+
+    It leverages the :doc:`PropertyAccess Component </components/property_access>`
+    to read and write in the object. This allows it to access properties
+    directly or using getters, setters, hassers, issers, canners, adders and
+    removers. Names are generated by removing the ``get``, ``set``,
+    ``has``, ``is``, ``add`` or ``remove`` prefix from the method name and
+    transforming the first letter to lowercase (e.g. ``getFirstName()`` ->
+    ``firstName``).
+
+    During denormalization, it supports using the constructor as well as
+    the discovered methods.
+
+.. danger::
+
+    Always make sure the ``DateTimeNormalizer`` is registered when
+    serializing the ``DateTime`` or ``DateTimeImmutable`` classes to avoid
+    excessive memory usage and exposing internal details.
+
+Built-in Normalizers
+~~~~~~~~~~~~~~~~~~~~
+
+Besides the normalizers registered by default (see previous section), the
+serializer component also provides some extra normalizers.You can register
+these by defining a service and tag it with :ref:`serializer.normalizer <reference-dic-tags-serializer-normalizer>`.
+For instance, to use the ``CustomNormalizer`` you have to define a service
+like:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/services.yaml
+        services:
+            # ...
+
+            # if you're using autoconfigure, the tag will be automatically applied
+            Symfony\Component\Serializer\Normalizer\CustomNormalizer:
+                tags:
+                    # register the normalizer with a high priority (called earlier)
+                    - { name: 'serializer.normalizer', priority: 500 }
+
+    .. code-block:: xml
+
+        <!-- config/services.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd">
+
+            <services>
+                <!-- ... -->
+
+                <!-- if you're using autoconfigure, the tag will be automatically applied -->
+                <service id="Symfony\Component\Serializer\Normalizer\CustomNormalizer">
+                    <!-- register the normalizer with a high priority (called earlier) -->
+                    <tag name="serializer.normalizer"
+                        priority="500"
+                    />
+                </service>
+            </services>
+        </container>
+
+    .. code-block:: php
+
+        // config/services.php
+        namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+        use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
+
+        return function(ContainerConfigurator $container) {
+            // ...
+
+            // if you're using autoconfigure, the tag will be automatically applied
+            $services->set(CustomNormalizer::class)
+                // register the normalizer with a high priority (called earlier)
+                ->tag('serializer.normalizer', [
+                    'priority' => 500,
+                ])
+            ;
+        };
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\CustomNormalizer`
+    This normalizer calls a method on the PHP object when normalizing. The
+    PHP object must implement :class:`Symfony\\Component\\Serializer\\Normalizer\\NormalizableInterface`
+    and/or :class:`Symfony\\Component\\Serializer\\Normalizer\\DenormalizableInterface`.
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer`
+    This normalizer is an alternative to the default ``ObjectNormalizer``.
+    It reads the content of the class by calling the "getters" (public
+    methods starting with ``get``, ``has``, ``is`` or ``can``). It will
+    denormalize data by calling the constructor and the "setters" (public
+    methods starting with ``set``).
+
+    Objects are normalized to a map of property names and values (names are
+    generated by removing the ``get`` prefix from the method name and transforming
+    the first letter to lowercase; e.g. ``getFirstName()`` -> ``firstName``).
+
+:class:`Symfony\\Component\\Serializer\\Normalizer\\PropertyNormalizer`
+    This is yet another alternative to the ``ObjectNormalizer``. This
+    normalizer directly reads and writes public properties as well as
+    **private and protected** properties (from both the class and all of
+    its parent classes) by using `PHP reflection`_. It supports calling the
+    constructor during the denormalization process.
+
+    Objects are normalized to a map of property names to property values.
+
+    You can also limit the normalizer to only use properties with a specific
+    visibility (e.g. only public properties) using the
+    ``PropertyNormalizer::NORMALIZE_VISIBILITY`` context option. You can set it
+    to any combination of the ``PropertyNormalizer::NORMALIZE_PUBLIC``,
+    ``PropertyNormalizer::NORMALIZE_PROTECTED`` and
+    ``PropertyNormalizer::NORMALIZE_PRIVATE`` constants::
+
+        use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
+        // ...
+
+        $json = $serializer->serialize($person, 'json', [
+            // only serialize public properties
+            PropertyNormalizer::NORMALIZE_VISIBILITY => PropertyNormalizer::NORMALIZE_PUBLIC,
+
+            // serialize public and protected properties
+            PropertyNormalizer::NORMALIZE_VISIBILITY => PropertyNormalizer::NORMALIZE_PUBLIC | PropertyNormalizer::NORMALIZE_PROTECTED,
+        ]);
+
+Debugging the Serializer
+------------------------
+
+Use the ``debug:serializer`` command to dump the serializer metadata of a
+given class:
+
+.. code-block:: terminal
+
+    $ php bin/console debug:serializer 'App\Entity\Book'
+
+        App\Entity\Book
+        ---------------
+
+        +----------+------------------------------------------------------------+
+        | Property | Options                                                    |
+        +----------+------------------------------------------------------------+
+        | name     | [                                                          |
+        |          |   "groups" => [                                            |
+        |          |       "book:read",                                         |
+        |          |       "book:write",                                        |
+        |          |   ],                                                       |
+        |          |   "maxDepth" => 1,                                         |
         |          |   "serializedName" => "book_name",                         |
         |          |   "serializedPath" => null,                                |
         |          |   "ignore" => false,                                       |
@@ -539,42 +1506,637 @@ given class:
         |          |   ],                                                       |
         |          |   "maxDepth" => null,                                      |
         |          |   "serializedName" => null,                                |
-        |          |   "serializedPath" => [data][isbn],                        |
+        |          |   "serializedPath" => "[data][isbn]",                      |
         |          |   "ignore" => false,                                       |
         |          |   "normalizationContexts" => [],                           |
         |          |   "denormalizationContexts" => []                          |
         |          | ]                                                          |
         +----------+------------------------------------------------------------+
 
-Going Further with the Serializer
----------------------------------
+Advanced Serialization
+----------------------
+
+Skipping ``null`` Values
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, the Serializer will preserve properties containing a ``null`` value.
+You can change this behavior by setting the ``AbstractObjectNormalizer::SKIP_NULL_VALUES`` context option
+to ``true``::
+
+    class Person
+    {
+        public string $name = 'Jane Doe';
+        public ?string $gender = null;
+    }
+
+    $jsonContent = $serializer->serialize(new Person(), 'json', [
+        AbstractObjectNormalizer::SKIP_NULL_VALUES => true,
+    ]);
+    // $jsonContent contains {"name":"Jane Doe"}
+
+Handling Uninitialized Properties
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In PHP, typed properties have an ``uninitialized`` state which is different
+from the default ``null`` of untyped properties. When you try to access a typed
+property before giving it an explicit value, you get an error.
+
+To avoid the serializer throwing an error when serializing or normalizing
+an object with uninitialized properties, by default the ``ObjectNormalizer``
+catches these errors and ignores such properties.
+
+You can disable this behavior by setting the
+``AbstractObjectNormalizer::SKIP_UNINITIALIZED_VALUES`` context option to
+``false``::
+
+    class Person {
+        public string $name = 'Jane Doe';
+        public string $phoneNumber; // uninitialized
+    }
+
+    $jsonContent = $normalizer->serialize(new Dummy(), 'json', [
+        AbstractObjectNormalizer::SKIP_UNINITIALIZED_VALUES => false,
+    ]);
+    // throws Symfony\Component\PropertyAccess\Exception\UninitializedPropertyException
+    // as the ObjectNormalizer cannot read uninitialized properties
+
+.. note::
+
+    Using :class:`Symfony\\Component\\Serializer\\Normalizer\\PropertyNormalizer`
+    or :class:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer`
+    with ``AbstractObjectNormalizer::SKIP_UNINITIALIZED_VALUES`` context
+    option set to ``false`` will throw an ``\Error`` instance if the given
+    object has uninitialized properties as the normalizers cannot read them
+    (directly or via getter/isser methods).
+
+.. _component-serializer-handling-circular-references:
+
+Handling Circular References
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Circular references are common when dealing with associated objects::
+
+    class Organization
+    {
+        public function __construct(
+            private string $name,
+            private array $members = []
+        ) {
+        }
+
+        public function getName(): string
+        {
+            return $this->name;
+        }
+
+        public function addMember(Member $member): void
+        {
+            $this->members[] = $member;
+        }
+
+        public function getMembers(): array
+        {
+            return $this->members;
+        }
+    }
+
+    class Member
+    {
+        private Organization $organization;
+
+        public function __construct(
+            private string $name
+        ) {
+        }
+
+        public function getName(): string
+        {
+            return $this->name;
+        }
+
+        public function setOrganization(Organization $organization): void
+        {
+            $this->organization = $organization;
+        }
+
+        public function getOrganization(): Organization
+        {
+            return $this->organization;
+        }
+    }
+
+To avoid infinite loops, the normalizers throw a
+:class:`Symfony\\Component\\Serializer\\Exception\\CircularReferenceException`
+when such a case is encountered::
+
+    $organization = new Organization('Les-Tilleuls.coop');
+    $member = new Member('Kévin');
+
+    $organization->addMember($member);
+    $member->setOrganization($organization);
+
+    $jsonContent = $serializer->serialize($organization, 'json');
+    // throws a CircularReferenceException
+
+The key ``circular_reference_limit`` in the context sets the number of
+times it will serialize the same object before considering it a circular
+reference. The default value is ``1``.
+
+Instead of throwing an exception, circular references can also be handled
+by custom callables. This is especially useful when serializing entities
+having unique identifiers::
+
+    use Symfony\Component\Serializer\Exception\CircularReferenceException;
+
+    $context = [
+        AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function (object $object, ?string $format, array $context): string {
+            if (!$object instanceof Organization) {
+                throw new CircularReferenceException('A circular reference has been detected when serializing the object of class "'.get_debug_type($object).'".');
+            }
+
+            // serialize the nested Organization with only the name (and not the members)
+            return $object->getName();
+        },
+    ];
+
+    $jsonContent = $serializer->serialize($organization, 'json', $context);
+    // $jsonContent contains {"name":"Les-Tilleuls.coop","members":[{"name":"K\u00e9vin", organization: "Les-Tilleuls.coop"}]}
+
+.. _serializer_handling-serialization-depth:
+
+Handling Serialization Depth
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The serializer can also detect nested objects of the same class and limit
+the serialization depth. This is useful for tree structures, where the same
+object is nested multiple times.
+
+For instance, assume a data structure of a family tree::
+
+    // ...
+    class Person
+    {
+        // ...
+
+        public function __construct(
+            private string $name,
+            private ?self $mother
+        ) {
+        }
+
+        public function getName(): string
+        {
+            return $this->name;
+        }
+
+        public function getMother(): ?self
+        {
+            return $this->mother;
+        }
+
+        // ...
+    }
+
+    // ...
+    $greatGrandmother = new Person('Elizabeth', null);
+    $grandmother = new Person('Jane', $greatGrandmother);
+    $mother = new Person('Sophie', $grandmother);
+    $child = new Person('Joe', $mother);
+
+You can specify the maximum depth for a given property. For instance, you
+can set the max depth to ``1`` to always only serialize someone's mother
+(and not their grandmother, etc.):
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Model/Person.php
+        namespace App\Model;
+
+        use Symfony\Component\Serializer\Attribute\MaxDepth;
+
+        class Person
+        {
+            #[MaxDepth(1)]
+            private ?self $mother;
+
+            // ...
+        }
+
+    .. code-block:: yaml
+
+        # config/serializer/person.yaml
+        App\Model\Person:
+            attributes:
+                mother:
+                    max_depth: 1
+
+    .. code-block:: xml
+
+        <!-- config/serializer/person.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
+                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
+        >
+            <class name="App\Model\Person">
+                <attribute name="mother" max-depth="1"/>
+            </class>
+        </serializer>
+
+To limit the serialization depth, you must set the
+``AbstractObjectNormalizer::ENABLE_MAX_DEPTH`` key to ``true`` in the
+context (or the default context specified in ``framework.yaml``)::
+
+    // ...
+    $greatGrandmother = new Person('Elizabeth', null);
+    $grandmother = new Person('Jane', $greatGrandmother);
+    $mother = new Person('Sophie', $grandmother);
+    $child = new Person('Joe', $mother);
+
+    $jsonContent = $serializer->serialize($child, null, [
+        AbstractObjectNormalizer::ENABLE_MAX_DEPTH => true
+    ]);
+    // $jsonContent contains {"name":"Joe","mother":{"name":"Sophie"}}
+
+You can also configure a custom callable that is used when the maximum
+depth is reached. This can be used to for instance return the unique
+identifier of the next nested object, instead of omitting the property::
+
+    use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
+    // ...
+
+    $greatGrandmother = new Person('Elizabeth', null);
+    $grandmother = new Person('Jane', $greatGrandmother);
+    $mother = new Person('Sophie', $grandmother);
+    $child = new Person('Joe', $mother);
 
-`API Platform`_ provides an API system supporting the following formats:
+    // all callback parameters are optional (you can omit the ones you don't use)
+    $maxDepthHandler = function (object $innerObject, object $outerObject, string $attributeName, ?string $format = null, array $context = []): ?string {
+        // return only the name of the next person in the tree
+        return $innerObject instanceof Person ? $innerObject->getName() : null;
+    };
 
-* `JSON-LD`_ along with the `Hydra Core Vocabulary`_
-* `OpenAPI`_ v2 (formerly Swagger) and v3
-* `GraphQL`_
-* `JSON:API`_
-* `HAL`_
-* JSON
-* XML
-* YAML
-* CSV
+    $jsonContent = $serializer->serialize($child, null, [
+        AbstractObjectNormalizer::ENABLE_MAX_DEPTH => true,
+        AbstractObjectNormalizer::MAX_DEPTH_HANDLER => $maxDepthHandler,
+    ]);
+    // $jsonContent contains {"name":"Joe","mother":{"name":"Sophie","mother":"Jane"}}
+
+Using Callbacks to Serialize Properties with Object Instances
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When serializing, you can set a callback to format a specific object
+property. This can be used instead of
+:ref:`defining the context for a group <serializer-context-group>`::
+
+    $person = new Person('cordoval', 34);
+    $person->setCreatedAt(new \DateTime('now'));
+
+    $context = [
+        AbstractNormalizer::CALLBACKS => [
+            // all callback parameters are optional (you can omit the ones you don't use)
+            'createdAt' => function (object $attributeValue, object $object, string $attributeName, ?string $format = null, array $context = []) {
+                return $attributeValue instanceof \DateTime ? $attributeValue->format(\DateTime::ATOM) : '';
+            },
+        ],
+    ];
+    $jsonContent = $serializer->serialize($person, 'json', $context);
+    // $jsonContent contains {"name":"cordoval","age":34,"createdAt":"2014-03-22T09:43:12-0500"}
+
+Advanced Deserialization
+------------------------
+
+Require all Properties
+~~~~~~~~~~~~~~~~~~~~~~
+
+By default, the Serializer will add ``null`` to nullable properties when
+the parameters for those are not provided. You can change this behavior by
+setting the ``AbstractNormalizer::REQUIRE_ALL_PROPERTIES`` context option
+to ``true``::
+
+    class Person
+    {
+        public function __construct(
+            public string $firstName,
+            public ?string $lastName,
+        ) {
+        }
+    }
+
+    // ...
+    $data = ['firstName' => 'John'];
+    $person = $serializer->deserialize($data, Person::class, 'json', [
+        AbstractNormalizer::REQUIRE_ALL_PROPERTIES => true,
+    ]);
+    // throws Symfony\Component\Serializer\Exception\MissingConstructorArgumentException
+
+Collecting Type Errors While Denormalizing
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When denormalizing a payload to an object with typed properties, you'll get an
+exception if the payload contains properties that don't have the same type as
+the object.
+
+Use the ``COLLECT_DENORMALIZATION_ERRORS`` option to collect all exceptions
+at once, and to get the object partially denormalized::
+
+    try {
+        $person = $serializer->deserialize($jsonString, Person::class, 'json', [
+            DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true,
+        ]);
+    } catch (PartialDenormalizationException $e) {
+        $violations = new ConstraintViolationList();
+
+        /** @var NotNormalizableValueException $exception */
+        foreach ($e->getErrors() as $exception) {
+            $message = sprintf('The type must be one of "%s" ("%s" given).', implode(', ', $exception->getExpectedTypes()), $exception->getCurrentType());
+            $parameters = [];
+            if ($exception->canUseMessageForUser()) {
+                $parameters['hint'] = $exception->getMessage();
+            }
+            $violations->add(new ConstraintViolation($message, '', $parameters, null, $exception->getPath(), null));
+        }
+
+        // ... return violation list to the user
+    }
+
+.. _serializer-populate-existing-object:
+
+Deserializing in an Existing Object
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The serializer can also be used to update an existing object. You can do
+this by configuring the ``object_to_populate`` serializer context option::
+
+    use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
+
+    // ...
+    $person = new Person('Jane Doe', 59);
+
+    $serializer->deserialize($jsonData, Person::class, 'json', [
+        AbstractNormalizer::OBJECT_TO_POPULATE => $person,
+    ]);
+    // instead of returning a new object, $person is updated instead
+
+.. note::
+
+    The ``AbstractNormalizer::OBJECT_TO_POPULATE`` option is only used for
+    the top level object. If that object is the root of a tree structure,
+    all child elements that exist in the normalized data will be re-created
+    with new instances.
+
+    When the ``AbstractObjectNormalizer::DEEP_OBJECT_TO_POPULATE`` context
+    option is set to ``true``, existing children of the root ``OBJECT_TO_POPULATE``
+    are updated from the normalized data, instead of the denormalizer
+    re-creating them. This only works for single child objects, not for
+    arrays of objects. Those will still be replaced when present in the
+    normalized data.
+
+.. _serializer_interfaces-and-abstract-classes:
+
+Deserializing Interfaces and Abstract Classes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When working with associated objects, a property sometimes reference an
+interface or abstract class. When deserializing these properties, the
+Serializer has to know which concrete class to initialize. This is done
+using a *discriminator class mapping*.
+
+Imagine there is an ``InvoiceItemInterface`` that is implemented by the
+``Product`` and ``Shipping`` objects. When serializing an object, the
+serializer will add an extra "discriminator attribute". This contains
+either ``product`` or ``shipping``. The discriminator class map maps
+these type names to the real PHP class name when deserializing:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        namespace App\Model;
+
+        use Symfony\Component\Serializer\Attribute\DiscriminatorMap;
+
+        #[DiscriminatorMap(
+            typeProperty: 'type',
+            mapping: [
+                'product' => Product::class,
+                'shipping' => Shipping::class,
+            ]
+        )]
+        interface InvoiceItemInterface
+        {
+            // ...
+        }
+
+    .. code-block:: yaml
+
+        App\Model\InvoiceItemInterface:
+            discriminator_map:
+                type_property: type
+                mapping:
+                    product: 'App\Model\Product'
+                    shipping: 'App\Model\Shipping'
+
+    .. code-block:: xml
+
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
+                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
+        >
+            <class name="App\Model\InvoiceItemInterface">
+                <discriminator-map type-property="type">
+                    <mapping type="product" class="App\Model\Product"/>
+                    <mapping type="shipping" class="App\Model\Shipping"/>
+                </discriminator-map>
+            </class>
+        </serializer>
+
+With the discriminator map configured, the serializer can now pick the
+correct class for properties typed as ``InvoiceItemInterface``::
+
+.. configuration-block::
+
+    .. code-block:: php-symfony
+
+        class InvoiceLine
+        {
+            public function __construct(
+                private InvoiceItemInterface $invoiceItem
+            ) {
+                $this->invoiceItem = $invoiceItem;
+            }
+
+            public function getInvoiceItem(): InvoiceItemInterface
+            {
+                return $this->invoiceItem;
+            }
+
+            // ...
+        }
+
+        // ...
+        $invoiceLine = new InvoiceLine(new Product());
+
+        $jsonString = $serializer->serialize($invoiceLine, 'json');
+        // $jsonString contains {"type":"product",...}
+
+        $invoiceLine = $serializer->deserialize($jsonString, InvoiceLine::class, 'json');
+        // $invoiceLine contains new InvoiceLine(new Product(...))
+
+    .. code-block:: php-standalone
+
+        // ...
+        use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata;
+        use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
+        use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader;
+        use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
+        use Symfony\Component\Serializer\Serializer;
+
+        class InvoiceLine
+        {
+            public function __construct(
+                private InvoiceItemInterface $invoiceItem
+            ) {
+                $this->invoiceItem = $invoiceItem;
+            }
+
+            public function getInvoiceItem(): InvoiceItemInterface
+            {
+                return $this->invoiceItem;
+            }
+
+            // ...
+        }
+
+        // ...
+
+        // Configure a loader to retrieve mapping information like DiscriminatorMap.
+        // E.g. when using PHP attributes:
+        $classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
+        $discriminator = new ClassDiscriminatorFromClassMetadata($classMetadataFactory);
+        $normalizers = [
+            new ObjectNormalizer($classMetadataFactory, null, null, null, $discriminator),
+        ];
+
+        $serializer = new Serializer($normalizers, $encoders);
+
+        $invoiceLine = new InvoiceLine(new Product());
+
+        $jsonString = $serializer->serialize($invoiceLine, 'json');
+        // $jsonString contains {"type":"product",...}
+
+        $invoiceLine = $serializer->deserialize($jsonString, InvoiceLine::class, 'json');
+        // $invoiceLine contains new InvoiceLine(new Product(...))
+
+.. _serializer-unwrapping-denormalizer:
+
+Deserializing Input Partially (Unwrapping)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The serializer will always deserialize the complete input string into PHP
+values. When connecting with third party APIs, you often only need a
+specific part of the returned response.
+
+To avoid deserializing the whole response, you can use the
+:class:`Symfony\\Component\\Serializer\\Normalizer\\UnwrappingDenormalizer`
+and "unwrap" the input data::
 
-It is built on top of the Symfony Framework and its Serializer
-component. It provides custom normalizers and a custom encoder, custom metadata
-and a caching system.
+    $jsonData = '{"result":"success","data":{"person":{"name": "Jane Doe","age":57}}}';
+    $data = $serialiser->deserialize($jsonData, Object::class, [
+        UnwrappingDenormalizer::UNWRAP_PATH => '[data][person]',
+    ]);
+    // $data is Person(name: 'Jane Doe', age: 57)
+
+The ``unwrap_path`` is a :ref:`property path <property-access-reading-arrays>`
+of the PropertyAccess component, applied on the denormalized array.
+
+Handling Constructor Arguments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If the class constructor defines arguments, as usually happens with
+`Value Objects`_, the serializer will match the parameter names with the
+deserialized attributes. If some parameters are missing, a
+:class:`Symfony\\Component\\Serializer\\Exception\\MissingConstructorArgumentsException`
+is thrown.
+
+In these cases, use the ``default_constructor_arguments`` context option to
+define default values for the missing parameters::
+
+    use App\Model\Person;
+    use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
+    // ...
+
+    $jsonData = '{"age":39,"name":"Jane Doe"}';
+    $person = $serializer->deserialize($jsonData, Person::class, 'json', [
+        AbstractNormalizer::DEFAULT_CONSTRUCTOR_ARGUMENTS => [
+            Person::class => ['sportsperson' => true],
+        ],
+    ]);
+    // $person is Person(name: 'Jane Doe', age: 39, sportsperson: true);
+
+Recursive Denormalization and Type Safety
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When a ``PropertyTypeExtractor`` is available, the normalizer will also
+check that the data to denormalize matches the type of the property (even
+for primitive types). For instance, if a ``string`` is provided, but the
+type of the property is ``int``, an
+:class:`Symfony\\Component\\Serializer\\Exception\\UnexpectedValueException`
+will be thrown. The type enforcement of the properties can be disabled by
+setting the serializer context option
+``ObjectNormalizer::DISABLE_TYPE_ENFORCEMENT`` to ``true``.
+
+Handling Boolean Values
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 7.1
+
+    The ``AbstractNormalizer::FILTER_BOOL`` context option was introduced in Symfony 7.1.
+
+PHP considers many different values as true or false. For example, the
+strings ``true``, ``1``, and ``yes`` are considered true, while
+``false``, ``0``, and ``no`` are considered false.
+
+When deserializing, the Serializer component can take care of this
+automatically. This can be done by using the ``AbstractNormalizer::FILTER_BOOL``
+context option::
 
-If you want to leverage the full power of the Symfony Serializer component,
-take a look at how this bundle works.
+    use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
+    // ...
+
+    $person = $serializer->denormalize(['sportsperson' => 'yes'], Person::class, context: [
+        AbstractNormalizer::FILTER_BOOL => true
+    ]);
+    // $person contains a Person instance with sportsperson set to true
+
+This context makes the deserialization process behave like the
+:phpfunction:`filter_var` function with the ``FILTER_VALIDATE_BOOL`` flag.
+
+.. _serializer-enabling-metadata-cache:
+
+Configuring the Metadata Cache
+------------------------------
+
+The metadata for the serializer is automatically cached to enhance application
+performance. By default, the serializer uses the ``cache.system`` cache pool
+which is configured using the :ref:`cache.system <reference-cache-system>`
+option.
+
+Going Further with the Serializer
+---------------------------------
 
 .. toctree::
+    :glob:
     :maxdepth: 1
 
-    serializer/custom_encoders
-    serializer/custom_normalizer
-    serializer/custom_context_builders
+    serializer/*
 
+.. _`JMS serializer`: https://github.com/schmittjoh/serializer
 .. _`API Platform`: https://api-platform.com
 .. _`JSON-LD`: https://json-ld.org
 .. _`Hydra Core Vocabulary`: https://www.hydra-cg.com/
@@ -582,3 +2144,10 @@ take a look at how this bundle works.
 .. _`GraphQL`: https://graphql.org
 .. _`JSON:API`: https://jsonapi.org
 .. _`HAL`: https://stateless.group/hal_specification.html
+.. _`RFC 7807`: https://tools.ietf.org/html/rfc7807
+.. _`RFC 4122`: https://tools.ietf.org/html/rfc4122
+.. _`RFC 3339`: https://tools.ietf.org/html/rfc3339#section-5.8
+.. _`list of PHP timezones`: https://www.php.net/manual/en/timezones.php
+.. _`data URI`: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
+.. _`PHP reflection`: https://php.net/manual/en/book.reflection.php
+.. _`Value Objects`: https://en.wikipedia.org/wiki/Value_object
diff --git a/serializer/custom_context_builders.rst b/serializer/custom_context_builders.rst
index 00d08ef71d3..8eeb584d761 100644
--- a/serializer/custom_context_builders.rst
+++ b/serializer/custom_context_builders.rst
@@ -1,11 +1,9 @@
 How to Create your Custom Context Builder
 =========================================
 
-The :doc:`Serializer Component </components/serializer>` uses Normalizers
-and Encoders to transform any data to any data-structure (e.g. JSON).
-That serialization process can be configured thanks to a
-:ref:`serialization context <serializer_serializer-context>`, which can be built thanks to
-:ref:`context builders <component-serializer-context-builders>`.
+That serialization process of the :doc:`Serializer Component </serializer>`
+can be configured by the :ref:`serialization context <serializer-context>`,
+which can be built thanks to :ref:`context builders <serializer-using-context-builders>`.
 
 Each built-in normalizer/encoder has its related context builder. However, you
 may want to create a custom context builder for your
diff --git a/serializer/custom_encoders.rst b/serializer/custom_encoders.rst
deleted file mode 100644
index dca6aa12ec4..00000000000
--- a/serializer/custom_encoders.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-How to Create your Custom Encoder
-=================================
-
-The :doc:`Serializer Component </components/serializer>` uses Normalizers
-to transform any data to an array. Then, by leveraging *Encoders*, that data can
-be converted into any data-structure (e.g. JSON).
-
-The Component provides several built-in encoders that are described
-:doc:`in the serializer component </components/serializer>` but you may want
-to use another structure that's not supported.
-
-Creating a new encoder
-----------------------
-
-Imagine you want to serialize and deserialize YAML. For that you'll have to
-create your own encoder that uses the
-:doc:`Yaml Component </components/yaml>`::
-
-    // src/Serializer/YamlEncoder.php
-    namespace App\Serializer;
-
-    use Symfony\Component\Serializer\Encoder\DecoderInterface;
-    use Symfony\Component\Serializer\Encoder\EncoderInterface;
-    use Symfony\Component\Yaml\Yaml;
-
-    class YamlEncoder implements EncoderInterface, DecoderInterface
-    {
-        public function encode($data, string $format, array $context = []): string
-        {
-            return Yaml::dump($data);
-        }
-
-        public function supportsEncoding(string $format, array $context = []): bool
-        {
-            return 'yaml' === $format;
-        }
-
-        public function decode(string $data, string $format, array $context = []): array
-        {
-            return Yaml::parse($data);
-        }
-
-        public function supportsDecoding(string $format, array $context = []): bool
-        {
-            return 'yaml' === $format;
-        }
-    }
-
-Registering it in your app
---------------------------
-
-If you use the Symfony Framework, then you probably want to register this encoder
-as a service in your app. If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`,
-that's done automatically!
-
-.. tip::
-
-    If you're not using :ref:`autoconfigure <services-autoconfigure>`, make sure
-    to register your class as a service and tag it with ``serializer.encoder``.
-
-Now you'll be able to serialize and deserialize YAML!
diff --git a/serializer/custom_name_converter.rst b/serializer/custom_name_converter.rst
new file mode 100644
index 00000000000..49dafb02cc4
--- /dev/null
+++ b/serializer/custom_name_converter.rst
@@ -0,0 +1,112 @@
+How to Create your Custom Name Converter
+========================================
+
+The Serializer Component uses :ref:`name converters <serializer-name-conversion>`
+to transform the attribute names (e.g. from snake_case in JSON to CamelCase
+for PHP properties).
+
+Imagine you have the following object::
+
+    namespace App\Model;
+
+    class Company
+    {
+        public string $name;
+        public string $address;
+    }
+
+And in the serialized form, all attributes must be prefixed by ``org_`` like
+the following:
+
+.. code-block:: json
+
+    {"org_name": "Acme Inc.", "org_address": "123 Main Street, Big City"}
+
+A custom name converter can handle such cases::
+
+    namespace App\Serializer;
+
+    use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
+
+    class OrgPrefixNameConverter implements NameConverterInterface
+    {
+        public function normalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
+        {
+            // during normalization, add the prefix
+            return 'org_'.$propertyName;
+        }
+
+        public function denormalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
+        {
+            // remove the 'org_' prefix on denormalizing
+            return str_starts_with($propertyName, 'org_') ? substr($propertyName, 4) : $propertyName;
+        }
+    }
+
+.. versionadded:: 7.1
+
+    Accessing the current class name, format and context via
+    :method:`Symfony\\Component\\Serializer\\NameConverter\\NameConverterInterface::normalize`
+    and :method:`Symfony\\Component\\Serializer\\NameConverter\\NameConverterInterface::denormalize`
+    was introduced in Symfony 7.1.
+
+.. note::
+
+    You can also implement
+    :class:`Symfony\\Component\\Serializer\\NameConverter\\AdvancedNameConverterInterface`
+    to access the current class name, format and context.
+
+Then, configure the serializer to use your name converter:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/serializer.yaml
+        framework:
+            serializer:
+                # pass the service ID of your name converter
+                name_converter: 'App\Serializer\OrgPrefixNameConverter'
+
+    .. code-block:: xml
+
+        <!-- config/packages/serializer.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <framework:config>
+                <!-- pass the service ID of your name converter -->
+                <framework:serializer
+                    name-converter="App\Serializer\OrgPrefixNameConverter"
+                />
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/serializer.php
+        use App\Serializer\OrgPrefixNameConverter;
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework) {
+            $framework->serializer()
+                // pass the service ID of your name converter
+                ->nameConverter(OrgPrefixNameConverter::class)
+            ;
+        };
+
+Now, when using the serializer in the application, all attributes will be
+prefixed by ``org_``::
+
+    // ...
+    $company = new Company('Acme Inc.', '123 Main Street, Big City');
+
+    $json = $serializer->serialize($company, 'json');
+    // {"org_name": "Acme Inc.", "org_address": "123 Main Street, Big City"}
+    $companyCopy = $serializer->deserialize($json, Company::class, 'json');
+    // Same data as $company
diff --git a/serializer/custom_normalizer.rst b/serializer/custom_normalizer.rst
index 1519c2adf22..10092c6baa7 100644
--- a/serializer/custom_normalizer.rst
+++ b/serializer/custom_normalizer.rst
@@ -1,10 +1,11 @@
 How to Create your Custom Normalizer
 ====================================
 
-The :doc:`Serializer component </components/serializer>` uses
-normalizers to transform any data into an array. The component provides several
-:ref:`built-in normalizers <component-serializer-normalizers>` but you may need to create
-your own normalizer to transform an unsupported data structure.
+The :doc:`Serializer component </serializer>` uses normalizers to transform
+any data into an array. The component provides several
+ref:`built-in normalizers <serializer-built-in-normalizers>` but you may
+need to create your own normalizer to transform an unsupported data
+structure.
 
 Creating a New Normalizer
 -------------------------
@@ -68,6 +69,63 @@ a service and :doc:`tagged </service_container/tags>` with ``serializer.normaliz
 If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`,
 this is done automatically!
 
+If you're not using ``autoconfigure``, you have to tag the service with
+``serializer.normalizer``. You can also use this method to set a priority
+(higher means it's called earlier in the process):
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/services.yaml
+        services:
+            # ...
+
+            App\Serializer\TopicNormalizer:
+                tags:
+                    # register the normalizer with a high priority (called earlier)
+                    - { name: 'serializer.normalizer', priority: 500 }
+
+    .. code-block:: xml
+
+        <!-- config/services.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd">
+
+            <services>
+                <!-- ... -->
+
+                <service id="App\Serializer\TopicNormalizer">
+                    <!-- register the normalizer with a high priority (called earlier) -->
+                    <tag name="serializer.normalizer"
+                        priority="500"
+                    />
+                </service>
+            </services>
+        </container>
+
+    .. code-block:: php
+
+        // config/services.php
+        namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+        use App\Serializer\TopicNormalizer;
+
+        return function(ContainerConfigurator $container) {
+            // ...
+
+            // if you're using autoconfigure, the tag will be automatically applied
+            $services->set(TopicNormalizer::class)
+                // register the normalizer with a high priority (called earlier)
+                ->tag('serializer.normalizer', [
+                    'priority' => 500,
+                ])
+            ;
+        };
+
 Performance of Normalizers/Denormalizers
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/serializer/encoders.rst b/serializer/encoders.rst
new file mode 100644
index 00000000000..d5a98356156
--- /dev/null
+++ b/serializer/encoders.rst
@@ -0,0 +1,373 @@
+Serializer Encoders
+===================
+
+The Serializer component provides several built-in encoders:
+
+:class:`Symfony\\Component\\Serializer\\Encoder\\JsonEncoder`
+    This class encodes and decodes data in `JSON`_.
+
+:class:`Symfony\\Component\\Serializer\\Encoder\\XmlEncoder`
+    This class encodes and decodes data in `XML`_.
+
+:class:`Symfony\\Component\\Serializer\\Encoder\\YamlEncoder`
+    This encoder encodes and decodes data in `YAML`_. This encoder requires the
+    :doc:`Yaml Component </components/yaml>`.
+
+:class:`Symfony\\Component\\Serializer\\Encoder\\CsvEncoder`
+    This encoder encodes and decodes data in `CSV`_.
+
+.. note::
+
+    You can also create your own encoder to use another structure. Read more at
+    :ref:`Creating a Custom Encoder <serializer-custom-encoder>` below.
+
+All these encoders are enabled by default when using the Serializer component
+in a Symfony application.
+
+The ``JsonEncoder``
+-------------------
+
+The ``JsonEncoder`` encodes to and decodes from JSON strings, based on the PHP
+:phpfunction:`json_encode` and :phpfunction:`json_decode` functions.
+
+It can be useful to modify how these functions operate in certain instances
+by providing options such as ``JSON_PRESERVE_ZERO_FRACTION``. You can use
+the serialization context to pass in these options using the key
+``json_encode_options`` or ``json_decode_options`` respectively::
+
+    $this->serializer->serialize($data, 'json', [
+        'json_encode_options' => \JSON_PRESERVE_ZERO_FRACTION,
+    ]);
+
+All context options available for the JSON encoder are:
+
+``json_decode_associative`` (default: ``false``)
+    If set to ``true`` returns the result as an array, returns a nested ``stdClass`` hierarchy otherwise.
+``json_decode_detailed_errors`` (default: ``false``)
+    If set to ``true`` exceptions thrown on parsing of JSON are more specific. Requires `seld/jsonlint`_ package.
+``json_decode_options`` (default: ``0``)
+    Flags passed to :phpfunction:`json_decode` function.
+``json_encode_options`` (default: ``\JSON_PRESERVE_ZERO_FRACTION``)
+    Flags passed to :phpfunction:`json_encode` function.
+``json_decode_recursion_depth`` (default: ``512``)
+    Sets maximum recursion depth.
+
+The ``CsvEncoder``
+------------------
+
+The ``CsvEncoder`` encodes to and decodes from CSV. Serveral :ref:`context options <serializer-context>`
+are available to customize the behavior of the encoder:
+
+``csv_delimiter`` (default: ``,``)
+    Sets the field delimiter separating values (one character only).
+``csv_enclosure`` (default: ``"``)
+    Sets the field enclosure (one character only).
+``csv_end_of_line`` (default: ``\n``)
+    Sets the character(s) used to mark the end of each line in the CSV file.
+``csv_escape_char`` (default: empty string)
+
+    .. deprecated:: 7.2
+
+        The ``csv_escape_char`` option was deprecated in Symfony 7.2.
+
+    Sets the escape character (at most one character).
+``csv_key_separator`` (default: ``.``)
+    Sets the separator for array's keys during its flattening
+``csv_headers`` (default: ``[]``, inferred from input data's keys)
+    Sets the order of the header and data columns.
+    E.g. if you set it to ``['a', 'b', 'c']`` and serialize
+    ``['c' => 3, 'a' => 1, 'b' => 2]``, the order will be ``a,b,c`` instead
+    of the input order (``c,a,b``).
+``csv_escape_formulas`` (default: ``false``)
+    Escapes fields containing formulas by prepending them with a ``\t`` character.
+``as_collection`` (default: ``true``)
+    Always returns results as a collection, even if only one line is decoded.
+``no_headers`` (default: ``false``)
+    Setting to ``false`` will use first row as headers when denormalizing,
+    ``true`` generates numeric headers.
+``output_utf8_bom`` (default: ``false``)
+    Outputs special `UTF-8 BOM`_ along with encoded data.
+
+The ``XmlEncoder``
+------------------
+
+This encoder transforms PHP values into XML and vice versa.
+
+For example, take an object that is normalized as following::
+
+    $normalizedArray = ['foo' => [1, 2], 'bar' => true];
+
+The ``XmlEncoder`` will encode this object like:
+
+.. code-block:: xml
+
+    <?xml version="1.0" encoding="UTF-8" ?>
+    <response>
+        <foo>1</foo>
+        <foo>2</foo>
+        <bar>1</bar>
+    </response>
+
+The special ``#`` key can be used to define the data of a node::
+
+    ['foo' => ['@bar' => 'value', '#' => 'baz']];
+
+    /* is encoded as follows:
+       <?xml version="1.0"?>
+       <response>
+           <foo bar="value">
+              baz
+           </foo>
+       </response>
+     */
+
+Furthermore, keys beginning with ``@`` will be considered attributes, and
+the key  ``#comment`` can be used for encoding XML comments::
+
+    $encoder = new XmlEncoder();
+    $xml = $encoder->encode([
+        'foo' => ['@bar' => 'value'],
+        'qux' => ['#comment' => 'A comment'],
+    ], 'xml');
+    /* will return:
+       <?xml version="1.0"?>
+       <response>
+           <foo bar="value"/>
+           <qux><!-- A comment --!><qux>
+       </response>
+     */
+
+You can pass the context key ``as_collection`` in order to have the results
+always as a collection.
+
+.. note::
+
+    You may need to add some attributes on the root node::
+
+        $encoder = new XmlEncoder();
+        $encoder->encode([
+            '@attribute1' => 'foo',
+            '@attribute2' => 'bar',
+            '#' => ['foo' => ['@bar' => 'value', '#' => 'baz']]
+        ], 'xml');
+
+        // will return:
+        // <?xml version="1.0"?>
+        // <response attribute1="foo" attribute2="bar">
+        // <foo bar="value">baz</foo>
+        // </response>
+
+.. tip::
+
+    XML comments are ignored by default when decoding contents, but this
+    behavior can be changed with the optional context key ``XmlEncoder::DECODER_IGNORED_NODE_TYPES``.
+
+    Data with ``#comment`` keys are encoded to XML comments by default. This can be
+    changed by adding the ``\XML_COMMENT_NODE`` option to the ``XmlEncoder::ENCODER_IGNORED_NODE_TYPES``
+    key of the ``$defaultContext`` of the ``XmlEncoder`` constructor or
+    directly to the ``$context`` argument of the ``encode()`` method::
+
+        $xmlEncoder->encode($array, 'xml', [XmlEncoder::ENCODER_IGNORED_NODE_TYPES => [\XML_COMMENT_NODE]]);
+
+The ``XmlEncoder`` Context Options
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These are the options available on the :ref:`serializer context <serializer-context>`:
+
+``xml_format_output`` (default: ``false``)
+    If set to true, formats the generated XML with line breaks and indentation.
+``xml_version`` (default: ``1.0``)
+    Sets the XML version attribute.
+``xml_encoding`` (default: ``utf-8``)
+    Sets the XML encoding attribute.
+``xml_standalone`` (default: ``true``)
+    Adds standalone attribute in the generated XML.
+``xml_type_cast_attributes`` (default: ``true``)
+    This provides the ability to forget the attribute type casting.
+``xml_root_node_name`` (default: ``response``)
+    Sets the root node name.
+``as_collection`` (default: ``false``)
+    Always returns results as a collection, even if only one line is decoded.
+``decoder_ignored_node_types`` (default: ``[\XML_PI_NODE, \XML_COMMENT_NODE]``)
+    Array of node types (`DOM XML_* constants`_) to be ignored while decoding.
+``encoder_ignored_node_types`` (default: ``[]``)
+    Array of node types (`DOM XML_* constants`_) to be ignored while encoding.
+``load_options`` (default: ``\LIBXML_NONET | \LIBXML_NOBLANKS``)
+    XML loading `options with libxml`_.
+``save_options`` (default: ``0``)
+    XML saving `options with libxml`_.
+``remove_empty_tags`` (default: ``false``)
+    If set to ``true``, removes all empty tags in the generated XML.
+``cdata_wrapping`` (default: ``true``)
+    If set to ``false``, will not wrap any value containing one of the
+    following characters ( ``<``, ``>``, ``&``) in `a CDATA section`_ like
+    following: ``<![CDATA[...]]>``.
+``cdata_wrapping_pattern`` (default: ````/[<>&]/````)
+    A regular expression pattern to determine if a value should be wrapped
+    in a CDATA section.
+
+.. versionadded:: 7.1
+
+    The ``cdata_wrapping_pattern`` option was introduced in Symfony 7.1.
+
+
+Example with a custom ``context``::
+
+    use Symfony\Component\Serializer\Encoder\XmlEncoder;
+
+    $data = [
+        'id' => 'IDHNQIItNyQ',
+        'date' => '2019-10-24',
+    ];
+
+    $xmlEncoder->encode($data, 'xml', ['xml_format_output' => true]);
+    // outputs:
+    // <?xml version="1.0"?>
+    // <response>
+    //   <id>IDHNQIItNyQ</id>
+    //   <date>2019-10-24</date>
+    // </response>
+
+    $xmlEncoder->encode($data, 'xml', [
+        'xml_format_output' => true,
+        'xml_root_node_name' => 'track',
+        'encoder_ignored_node_types' => [
+            \XML_PI_NODE, // removes XML declaration (the leading xml tag)
+        ],
+    ]);
+    // outputs:
+    // <track>
+    //   <id>IDHNQIItNyQ</id>
+    //   <date>2019-10-24</date>
+    // </track>
+
+The ``YamlEncoder``
+-------------------
+
+This encoder requires the :doc:`Yaml Component </components/yaml>` and
+transforms from and to Yaml.
+
+Like other encoder, several :ref:`context options <serializer-context>` are
+available:
+
+``yaml_inline`` (default: ``0``)
+    The level where you switch to inline YAML.
+``yaml_indent`` (default: ``0``)
+    The level of indentation (used internally).
+``yaml_flags`` (default: ``0``)
+    A bit field of ``Yaml::DUMP_*``/``Yaml::PARSE_*`` constants to
+    customize the encoding/decoding YAML string.
+
+.. _serializer-custom-encoder:
+
+Creating a Custom Encoder
+-------------------------
+
+Imagine you want to serialize and deserialize `NEON`_. For that you'll have to
+create your own encoder::
+
+    // src/Serializer/YamlEncoder.php
+    namespace App\Serializer;
+
+    use Nette\Neon\Neon;
+    use Symfony\Component\Serializer\Encoder\DecoderInterface;
+    use Symfony\Component\Serializer\Encoder\EncoderInterface;
+
+    class NeonEncoder implements EncoderInterface, DecoderInterface
+    {
+        public function encode($data, string $format, array $context = [])
+        {
+            return Neon::encode($data);
+        }
+
+        public function supportsEncoding(string $format)
+        {
+            return 'neon' === $format;
+        }
+
+        public function decode(string $data, string $format, array $context = [])
+        {
+            return Neon::decode($data);
+        }
+
+        public function supportsDecoding(string $format)
+        {
+            return 'neon' === $format;
+        }
+    }
+
+.. tip::
+
+    If you need access to ``$context`` in your ``supportsDecoding`` or
+    ``supportsEncoding`` method, make sure to implement
+    ``Symfony\Component\Serializer\Encoder\ContextAwareDecoderInterface``
+    or ``Symfony\Component\Serializer\Encoder\ContextAwareEncoderInterface`` accordingly.
+
+Registering it in Your App
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you use the Symfony Framework, then you probably want to register this encoder
+as a service in your app. If you're using the
+:ref:`default services.yaml configuration <service-container-services-load-example>`,
+that's done automatically!
+
+If you're not using :ref:`autoconfigure <services-autoconfigure>`, make sure
+to register your class as a service and tag it with
+:ref:`serializer.encoder <reference-dic-tags-serializer-encoder>`:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/services.yaml
+        services:
+            # ...
+
+            App\Serializer\NeonEncoder:
+                tags: ['serializer.encoder']
+
+    .. code-block:: xml
+
+        <!-- config/services.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd">
+
+            <services>
+                <!-- ... -->
+
+                <service id="App\Serializer\NeonEncoder">
+                    <tag name="serializer.encoder"/>
+                </service>
+            </services>
+        </container>
+
+    .. code-block:: php
+
+        // config/services.php
+        namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+        use App\Serializer\NeonEncoder;
+
+        return function(ContainerConfigurator $container) {
+            // ...
+
+            $services->set(NeonEncoder::class)
+                ->tag('serializer.encoder')
+            ;
+        };
+
+Now you'll be able to serialize and deserialize NEON!
+
+.. _JSON: https://www.json.org/json-en.html
+.. _XML: https://www.w3.org/XML/
+.. _YAML: https://yaml.org/
+.. _CSV: https://tools.ietf.org/html/rfc4180
+.. _seld/jsonlint: https://github.com/Seldaek/jsonlint
+.. _`UTF-8 BOM`: https://en.wikipedia.org/wiki/Byte_order_mark
+.. _`DOM XML_* constants`: https://www.php.net/manual/en/dom.constants.php
+.. _`options with libxml`: https://www.php.net/manual/en/libxml.constants.php
+.. _`a CDATA section`: https://en.wikipedia.org/wiki/CDATA
+.. _NEON: https://ne-on.org/
diff --git a/service_container.rst b/service_container.rst
index 6eb86231b63..30b69b8aa14 100644
--- a/service_container.rst
+++ b/service_container.rst
@@ -608,7 +608,7 @@ accessor methods for parameters::
     // adds a new parameter
     $container->setParameter('mailer.transport', 'sendmail');
 
-.. caution::
+.. warning::
 
     The used ``.`` notation is a
     :ref:`Symfony convention <service-naming-conventions>` to make parameters
@@ -1421,7 +1421,7 @@ and ``site_update_manager.normal_users``. Thanks to the alias, if you type-hint
 If you want to pass the second, you'll need to :ref:`manually wire the service <services-wire-specific-service>`
 or to create a named :ref:`autowiring alias <autowiring-alias>`.
 
-.. caution::
+.. warning::
 
     If you do *not* create the alias and are :ref:`loading all services from src/ <service-container-services-load-example>`,
     then *three* services have been created (the automatic service + your two services)
diff --git a/service_container/compiler_passes.rst b/service_container/compiler_passes.rst
index fc5728685e0..11458a4e8e3 100644
--- a/service_container/compiler_passes.rst
+++ b/service_container/compiler_passes.rst
@@ -3,53 +3,85 @@ How to Work with Compiler Passes
 
 Compiler passes give you an opportunity to manipulate other
 :doc:`service definitions </service_container/definitions>` that have been
-registered with the service container. You can read about how to create them in
-the components section ":ref:`components-di-separate-compiler-passes`".
+registered with the service container.
 
-Compiler passes are registered in the ``build()`` method of the application kernel::
+.. _kernel-as-compiler-pass:
+
+If your compiler pass is relatively small, you can define it inside the
+application's ``Kernel`` class instead of creating a
+:ref:`separate compiler pass class <components-di-separate-compiler-passes>`.
+
+To do so, make your kernel implement :class:`Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface`
+and add the compiler pass code inside the ``process()`` method::
 
     // src/Kernel.php
     namespace App;
 
-    use App\DependencyInjection\Compiler\CustomPass;
     use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
+    use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
     use Symfony\Component\DependencyInjection\ContainerBuilder;
     use Symfony\Component\HttpKernel\Kernel as BaseKernel;
 
-    class Kernel extends BaseKernel
+    class Kernel extends BaseKernel implements CompilerPassInterface
     {
         use MicroKernelTrait;
 
         // ...
 
-        protected function build(ContainerBuilder $container): void
+        public function process(ContainerBuilder $container): void
         {
-            $container->addCompilerPass(new CustomPass());
+            // in this method you can manipulate the service container:
+            // for example, changing some container service:
+            $container->getDefinition('app.some_private_service')->setPublic(true);
+
+            // or processing tagged services:
+            foreach ($container->findTaggedServiceIds('some_tag') as $id => $tags) {
+                // ...
+            }
         }
     }
 
-.. _kernel-as-compiler-pass:
-
-One of the most common use-cases of compiler passes is to work with :doc:`tagged
-services </service_container/tags>`. In those cases, instead of creating a
-compiler pass, you can make the kernel implement
-:class:`Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface`
-and process the services inside the ``process()`` method::
+If you create separate compiler pass classes, enable them in the ``build()``
+method of the application kernel::
 
     // src/Kernel.php
     namespace App;
 
+    use App\DependencyInjection\Compiler\CustomPass;
     use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
-    use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
     use Symfony\Component\DependencyInjection\ContainerBuilder;
     use Symfony\Component\HttpKernel\Kernel as BaseKernel;
 
-    class Kernel extends BaseKernel implements CompilerPassInterface
+    class Kernel extends BaseKernel
     {
         use MicroKernelTrait;
 
         // ...
 
+        protected function build(ContainerBuilder $container): void
+        {
+            $container->addCompilerPass(new CustomPass());
+        }
+    }
+
+Working with Compiler Passes in Bundles
+---------------------------------------
+
+If your compiler pass is relatively small, you can add it directly in the main
+bundle class. To do so, make your bundle implement the
+:class:`Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface`
+and place the compiler pass code inside the ``process()`` method of the main
+bundle class::
+
+    // src/MyBundle/MyBundle.php
+    namespace App\MyBundle;
+
+    use App\DependencyInjection\Compiler\CustomPass;
+    use Symfony\Component\DependencyInjection\ContainerBuilder;
+    use Symfony\Component\HttpKernel\Bundle\AbstractBundle;
+
+    class MyBundle extends AbstractBundle
+    {
         public function process(ContainerBuilder $container): void
         {
             // in this method you can manipulate the service container:
@@ -63,12 +95,8 @@ and process the services inside the ``process()`` method::
         }
     }
 
-Working with Compiler Passes in Bundles
----------------------------------------
-
-:doc:`Bundles </bundles>` can define compiler passes in the ``build()`` method of
-the main bundle class (this is not needed when implementing the ``process()``
-method in the extension)::
+Alternatively, when using :ref:`separate compiler pass classes <components-di-separate-compiler-passes>`,
+bundles can enable them in the ``build()`` method of their main bundle class::
 
     // src/MyBundle/MyBundle.php
     namespace App\MyBundle;
@@ -88,7 +116,7 @@ method in the extension)::
     }
 
 If you are using custom :doc:`service tags </service_container/tags>` in a
-bundle then by convention, tag names consist of the name of the bundle
-(lowercase, underscores as separators), followed by a dot, and finally the
-"real" name. For example, if you want to introduce some sort of "transport" tag
-in your AcmeMailerBundle, you should call it ``acme_mailer.transport``.
+bundle, the convention is to format tag names by starting with the bundle's name
+in lowercase (using underscores as separators), followed by a dot, and finally
+the specific tag name. For example, to introduce a "transport" tag in your
+AcmeMailerBundle, you would name it ``acme_mailer.transport``.
diff --git a/service_container/definitions.rst b/service_container/definitions.rst
index e54a99237d9..a2a50591668 100644
--- a/service_container/definitions.rst
+++ b/service_container/definitions.rst
@@ -86,7 +86,7 @@ fetched from the container::
 
     // gets a specific argument
     $firstArgument = $definition->getArgument(0);
-    
+
     // adds a new named argument
     // '$argumentName' = the name of the argument in the constructor, including the '$' symbol
     $definition = $definition->setArgument('$argumentName', $argumentValue);
@@ -100,7 +100,7 @@ fetched from the container::
     // replaces all previously configured arguments with the passed array
     $definition->setArguments($arguments);
 
-.. caution::
+.. warning::
 
     Don't use ``get()`` to get a service that you want to inject as constructor
     argument, the service is not yet available. Instead, use a
diff --git a/service_container/lazy_services.rst b/service_container/lazy_services.rst
index 41f27d8448f..23d76a4cfbf 100644
--- a/service_container/lazy_services.rst
+++ b/service_container/lazy_services.rst
@@ -21,7 +21,7 @@ Configuring lazy services is one answer to this. With a lazy service, a
 like the ``mailer``, except that the ``mailer`` isn't actually instantiated
 until you interact with the proxy in some way.
 
-.. caution::
+.. warning::
 
     Lazy services do not support `final`_ or ``readonly`` classes, but you can use
     `Interface Proxifying`_ to work around this limitation.
diff --git a/service_container/service_decoration.rst b/service_container/service_decoration.rst
index b3bf0bc5864..e2cadbb0a4b 100644
--- a/service_container/service_decoration.rst
+++ b/service_container/service_decoration.rst
@@ -289,35 +289,35 @@ the ``decoration_priority`` option. Its value is an integer that defaults to
 
 .. configuration-block::
 
-        .. code-block:: php-attributes
+    .. code-block:: php-attributes
 
-            // ...
-            use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
-            use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated;
+        // ...
+        use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
+        use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated;
 
-            #[AsDecorator(decorates: Foo::class, priority: 5)]
-            class Bar
-            {
-                public function __construct(
-                    #[AutowireDecorated]
-                    private $inner,
-                ) {
-                }
-                // ...
+        #[AsDecorator(decorates: Foo::class, priority: 5)]
+        class Bar
+        {
+            public function __construct(
+                #[AutowireDecorated]
+                private $inner,
+            ) {
             }
+            // ...
+        }
 
-            #[AsDecorator(decorates: Foo::class, priority: 1)]
-            class Baz
-            {
-                public function __construct(
-                    #[AutowireDecorated]
-                    private $inner,
-                ) {
-                }
-
-                // ...
+        #[AsDecorator(decorates: Foo::class, priority: 1)]
+        class Baz
+        {
+            public function __construct(
+                #[AutowireDecorated]
+                private $inner,
+            ) {
             }
 
+            // ...
+        }
+
     .. code-block:: yaml
 
         # config/services.yaml
@@ -609,24 +609,24 @@ Three different behaviors are available:
 
 .. configuration-block::
 
-        .. code-block:: php-attributes
-
-            // ...
-            use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
-            use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated;
-            use Symfony\Component\DependencyInjection\ContainerInterface;
+    .. code-block:: php-attributes
 
-            #[AsDecorator(decorates: Mailer::class, onInvalid: ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]
-            class Bar
-            {
-                public function __construct(
-                    private #[AutowireDecorated] $inner,
-                ) {
-                }
+        // ...
+        use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
+        use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated;
+        use Symfony\Component\DependencyInjection\ContainerInterface;
 
-                // ...
+        #[AsDecorator(decorates: Mailer::class, onInvalid: ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]
+        class Bar
+        {
+            public function __construct(
+                #[AutowireDecorated] private $inner,
+            ) {
             }
 
+            // ...
+        }
+
     .. code-block:: yaml
 
         # config/services.yaml
@@ -673,7 +673,7 @@ Three different behaviors are available:
             ;
         };
 
-.. caution::
+.. warning::
 
     When using ``null``, you may have to update the decorator constructor in
     order to make decorated dependency nullable::
diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst
index 8afbb767e45..9c6451931d1 100644
--- a/service_container/service_subscribers_locators.rst
+++ b/service_container/service_subscribers_locators.rst
@@ -962,7 +962,7 @@ and compose your services with them::
         }
     }
 
-.. caution::
+.. warning::
 
     When creating these helper traits, the service id cannot be ``__METHOD__``
     as this will include the trait name, not the class name. Instead, use
diff --git a/service_container/tags.rst b/service_container/tags.rst
index 4ee2fbd21f2..bf50a191ba3 100644
--- a/service_container/tags.rst
+++ b/service_container/tags.rst
@@ -112,7 +112,7 @@ If you want to apply tags automatically for your own services, use the
                     ->tag('app.custom_tag');
         };
 
-.. caution::
+.. warning::
 
     If you're using PHP configuration, you need to call ``instanceof`` before
     any service registration to make sure tags are correctly applied.
@@ -1281,4 +1281,19 @@ be used directly on the class of the service you want to configure::
         // ...
     }
 
+You can apply the ``#[AsTaggedItem]`` attribute multiple times to register the
+same service under different indexes:
+
+    #[AsTaggedItem(index: 'handler_one', priority: 5)]
+    #[AsTaggedItem(index: 'handler_two', priority: 20)]
+    class SomeService
+    {
+        // ...
+    }
+
+.. versionadded:: 7.3
+
+    The feature to apply the ``#[AsTaggedItem]`` attribute multiple times was
+    introduced in Symfony 7.3.
+
 .. _`PHP constructor promotion`: https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion
diff --git a/session.rst b/session.rst
index 393cd24a898..0c5348ec9e6 100644
--- a/session.rst
+++ b/session.rst
@@ -419,7 +419,7 @@ session metadata files:
 Check out the Symfony config reference to learn more about the other available
 :ref:`Session configuration options <config-framework-session>`.
 
-.. caution::
+.. warning::
 
     Symfony sessions are incompatible with ``php.ini`` directive
     ``session.auto_start = 1`` This directive should be turned off in
@@ -492,12 +492,11 @@ the ``php.ini`` directive ``session.gc_maxlifetime``. The meaning in this contex
 that any stored session that was saved more than ``gc_maxlifetime`` ago should be
 deleted. This allows one to expire records based on idle time.
 
-However, some operating systems (e.g. Debian) do their own session handling and set
-the ``session.gc_probability`` variable to ``0`` to stop PHP doing garbage
-collection. That's why Symfony now overwrites this value to ``1``.
-
-If you wish to use the original value set in your ``php.ini``, add the following
-configuration:
+However, some operating systems (e.g. Debian) manage session handling differently
+and set the ``session.gc_probability`` variable to ``0`` to prevent PHP from performing
+garbage collection. By default, Symfony uses the value of the ``gc_probability``
+directive set in the ``php.ini`` file. If you can't modify this PHP setting, you
+can configure it directly in Symfony:
 
 .. code-block:: yaml
 
@@ -505,14 +504,19 @@ configuration:
     framework:
         session:
             # ...
-            gc_probability: null
+            gc_probability: 1
 
-You can configure these settings by passing ``gc_probability``, ``gc_divisor``
-and ``gc_maxlifetime`` in an array to the constructor of
+Alternatively, you can configure these settings by passing ``gc_probability``,
+``gc_divisor`` and ``gc_maxlifetime`` in an array to the constructor of
 :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage`
 or to the :method:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage::setOptions`
 method.
 
+.. versionadded:: 7.2
+
+    Using the ``php.ini`` directive as the default value for ``gc_probability``
+    was introduced in Symfony 7.2.
+
 .. _session-database:
 
 Store Sessions in a Database
@@ -1536,7 +1540,7 @@ event::
         }
     }
 
-.. caution::
+.. warning::
 
     In order to update the language immediately after a user has changed their
     language preferences, you also need to update the session when you change
diff --git a/setup.rst b/setup.rst
index 1d7081e93b7..b269da2c476 100644
--- a/setup.rst
+++ b/setup.rst
@@ -48,10 +48,10 @@ application:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ symfony new my_project_directory --version="7.2.x-dev" --webapp
+    $ symfony new my_project_directory --version="7.3.x-dev" --webapp
 
     # run this if you are building a microservice, console application or API
-    $ symfony new my_project_directory --version="7.2.x-dev"
+    $ symfony new my_project_directory --version="7.3.x-dev"
 
 The only difference between these two commands is the number of packages
 installed by default. The ``--webapp`` option installs extra packages to give
@@ -63,12 +63,12 @@ Symfony application using Composer:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ composer create-project symfony/skeleton:"7.2.x-dev" my_project_directory
+    $ composer create-project symfony/skeleton:"7.3.x-dev" my_project_directory
     $ cd my_project_directory
     $ composer require webapp
 
     # run this if you are building a microservice, console application or API
-    $ composer create-project symfony/skeleton:"7.2.x-dev" my_project_directory
+    $ composer create-project symfony/skeleton:"7.3.x-dev" my_project_directory
 
 No matter which command you run to create the Symfony application. All of them
 will create a new ``my_project_directory/`` directory, download some dependencies
diff --git a/setup/_update_all_packages.rst.inc b/setup/_update_all_packages.rst.inc
index a6a6c70e570..7b858c51351 100644
--- a/setup/_update_all_packages.rst.inc
+++ b/setup/_update_all_packages.rst.inc
@@ -9,7 +9,7 @@ this safely by running:
 
     $ composer update
 
-.. caution::
+.. warning::
 
     Beware, if you have some unspecific `version constraints`_ in your
     ``composer.json`` (e.g. ``dev-master``), this could upgrade some
diff --git a/setup/file_permissions.rst b/setup/file_permissions.rst
index 7bf2d0bf035..45195f21e31 100644
--- a/setup/file_permissions.rst
+++ b/setup/file_permissions.rst
@@ -67,12 +67,12 @@ Edit your web server configuration (commonly ``httpd.conf`` or ``apache2.conf``
 for Apache) and set its user to be the same as your CLI user (e.g. for Apache,
 update the ``User`` and ``Group`` directives).
 
-.. caution::
+.. danger::
 
     If this solution is used in a production server, be sure this user only has
     limited privileges (no access to private data or servers, execution of
-    unsafe binaries, etc.) as a compromised server would give to the hacker
-    those privileges.
+    unsafe binaries, etc.) as a compromised server would give those privileges
+    to the hacker.
 
 3. Without Using ACL
 ~~~~~~~~~~~~~~~~~~~~
@@ -89,7 +89,7 @@ and ``public/index.php`` files::
 
     umask(0000); // This will let the permissions be 0777
 
-.. caution::
+.. warning::
 
     Changing the ``umask`` is not thread-safe, so the ACL methods are recommended
     when they are available.
diff --git a/setup/symfony_server.rst b/setup/symfony_server.rst
index f8b7c6e35c4..2ea4da543fe 100644
--- a/setup/symfony_server.rst
+++ b/setup/symfony_server.rst
@@ -294,7 +294,7 @@ domains work:
     # Example with Cypress
     $ https_proxy=$(symfony proxy:url) ./node_modules/bin/cypress open
 
-.. caution::
+.. warning::
 
     Although env var names are always defined in uppercase, the ``https_proxy``
     env var `is treated differently`_ than other env vars and its name must be
@@ -357,7 +357,7 @@ There are several options that you can set using a ``.symfony.local.yaml`` confi
         use_gzip: true # Toggle GZIP compression
         no_workers: true # Do not start workers
 
-.. caution::
+.. warning::
 
     Setting domains in this configuration file will override any domains you set
     using the ``proxy:domain:attach`` command for the current project when you start
@@ -524,7 +524,7 @@ its location, same as for ``docker-compose``:
     If you have more than one Docker Compose file, you can provide them all
     separated by ``:`` as explained in the `Docker compose CLI env var reference`_.
 
-.. caution::
+.. warning::
 
     When using the Symfony binary with ``php bin/console`` (``symfony console ...``),
     the binary will **always** use environment variables detected via Docker and will
@@ -534,7 +534,7 @@ its location, same as for ``docker-compose``:
     ``symfony console doctrine:database:drop --force --env=test``, the command will drop the database
     defined in your Docker configuration and not the "test" one.
 
-.. caution::
+.. warning::
 
     Similar to other web servers, this tool automatically exposes all environment
     variables available in the CLI context. Ensure that this local server is not
diff --git a/setup/upgrade_major.rst b/setup/upgrade_major.rst
index 60983e299a6..d8520ad05b4 100644
--- a/setup/upgrade_major.rst
+++ b/setup/upgrade_major.rst
@@ -98,7 +98,7 @@ Now, you can start fixing the notices:
 Once you fixed them all, the command ends with ``0`` (success) and you're
 done!
 
-.. caution::
+.. warning::
 
     You will probably see many deprecations about incompatible native
     return types. See :ref:`Add Native Return Types <upgrading-native-return-types>`
diff --git a/setup/web_server_configuration.rst b/setup/web_server_configuration.rst
index e5a0c9e7fd9..acd76c342b9 100644
--- a/setup/web_server_configuration.rst
+++ b/setup/web_server_configuration.rst
@@ -49,60 +49,6 @@ listen on. Each pool can also be run under a different UID and GID:
     ; or listen on a TCP connection
     ; listen = 127.0.0.1:9000
 
-Apache
-------
-
-If you are running Apache 2.4+, you can use ``mod_proxy_fcgi`` to pass
-incoming requests to PHP-FPM. Install the Apache2 FastCGI mod
-(``libapache2-mod-fastcgi`` on Debian), enable ``mod_proxy`` and
-``mod_proxy_fcgi`` in your Apache configuration, and use the ``SetHandler``
-directive to pass requests for PHP files to PHP FPM:
-
-.. code-block:: apache
-
-    # /etc/apache2/conf.d/example.com.conf
-    <VirtualHost *:80>
-        ServerName example.com
-        ServerAlias www.example.com
-
-        # Uncomment the following line to force Apache to pass the Authorization
-        # header to PHP: required for "basic_auth" under PHP-FPM and FastCGI
-        #
-        # SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
-
-        <FilesMatch \.php$>
-            # when using PHP-FPM as a unix socket
-            SetHandler proxy:unix:/var/run/php/php8.3-fpm.sock|fcgi://dummy
-
-            # when PHP-FPM is configured to use TCP
-            # SetHandler proxy:fcgi://127.0.0.1:9000
-        </FilesMatch>
-
-        DocumentRoot /var/www/project/public
-        <Directory /var/www/project/public>
-            AllowOverride None
-            Require all granted
-            FallbackResource /index.php
-        </Directory>
-
-        # uncomment the following lines if you install assets as symlinks
-        # or run into problems when compiling LESS/Sass/CoffeeScript assets
-        # <Directory /var/www/project>
-        #     Options FollowSymlinks
-        # </Directory>
-
-        ErrorLog /var/log/apache2/project_error.log
-        CustomLog /var/log/apache2/project_access.log combined
-    </VirtualHost>
-
-.. note::
-
-    If you are doing some quick tests with Apache, you can also run
-    ``composer require symfony/apache-pack``. This package creates an ``.htaccess``
-    file in the ``public/`` directory with the necessary rewrite rules needed to serve
-    the Symfony application. However, in production, it's recommended to move these
-    rules to the main Apache configuration file (as shown above) to improve performance.
-
 Nginx
 -----
 
@@ -183,13 +129,67 @@ The **minimum configuration** to get your application running under Nginx is:
     If you have other PHP files in your public directory that need to be executed,
     be sure to include them in the ``location`` block above.
 
-.. caution::
+.. warning::
 
     After you deploy to production, make sure that you **cannot** access the ``index.php``
     script (i.e. ``http://example.com/index.php``).
 
 For advanced Nginx configuration options, read the official `Nginx documentation`_.
 
+Apache
+------
+
+If you are running Apache 2.4+, you can use ``mod_proxy_fcgi`` to pass
+incoming requests to PHP-FPM. Install the Apache2 FastCGI mod
+(``libapache2-mod-fastcgi`` on Debian), enable ``mod_proxy`` and
+``mod_proxy_fcgi`` in your Apache configuration, and use the ``SetHandler``
+directive to pass requests for PHP files to PHP FPM:
+
+.. code-block:: apache
+
+    # /etc/apache2/conf.d/example.com.conf
+    <VirtualHost *:80>
+        ServerName example.com
+        ServerAlias www.example.com
+
+        # Uncomment the following line to force Apache to pass the Authorization
+        # header to PHP: required for "basic_auth" under PHP-FPM and FastCGI
+        #
+        # SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
+
+        <FilesMatch \.php$>
+            # when using PHP-FPM as a unix socket
+            SetHandler proxy:unix:/var/run/php/php8.3-fpm.sock|fcgi://dummy
+
+            # when PHP-FPM is configured to use TCP
+            # SetHandler proxy:fcgi://127.0.0.1:9000
+        </FilesMatch>
+
+        DocumentRoot /var/www/project/public
+        <Directory /var/www/project/public>
+            AllowOverride None
+            Require all granted
+            FallbackResource /index.php
+        </Directory>
+
+        # uncomment the following lines if you install assets as symlinks
+        # or run into problems when compiling LESS/Sass/CoffeeScript assets
+        # <Directory /var/www/project>
+        #     Options FollowSymlinks
+        # </Directory>
+
+        ErrorLog /var/log/apache2/project_error.log
+        CustomLog /var/log/apache2/project_access.log combined
+    </VirtualHost>
+
+.. note::
+
+    If you are doing some quick tests with Apache, you can also run
+    ``composer require symfony/apache-pack``. This package creates an ``.htaccess``
+    file in the ``public/`` directory with the necessary rewrite rules needed to serve
+    the Symfony application. However, in production, it's recommended to move these
+    rules to the main Apache configuration file (as shown above) to improve performance.
+
 Caddy
 -----
 
diff --git a/string.rst b/string.rst
index 43d3a236ab6..e51e7d1b502 100644
--- a/string.rst
+++ b/string.rst
@@ -234,8 +234,10 @@ Methods to Change Case
     u('Foo: Bar-baz.')->snake(); // 'foo_bar_baz'
     // changes all graphemes/code points to kebab-case
     u('Foo: Bar-baz.')->kebab(); // 'foo-bar-baz'
-    // other cases can be achieved by chaining methods. E.g. PascalCase:
-    u('Foo: Bar-baz.')->camel()->title(); // 'FooBarBaz'
+    // changes all graphemes/code points to PascalCase
+    u('Foo: Bar-baz.')->pascal(); // 'FooBarBaz'
+    // other cases can be achieved by chaining methods, e.g. :
+    u('Foo: Bar-baz.')->camel()->upper(); // 'FOOBARBAZ'
 
 .. versionadded:: 7.1
 
@@ -246,6 +248,10 @@ Methods to Change Case
 
     The ``kebab()`` method was introduced in Symfony 7.2.
 
+.. versionadded:: 7.3
+
+    The ``pascal()`` method was introduced in Symfony 7.3.
+
 The methods of all string classes are case-sensitive by default. You can perform
 case-insensitive operations with the ``ignoreCase()`` method::
 
diff --git a/templates.rst b/templates.rst
index 9ae234f460b..50e052d69fd 100644
--- a/templates.rst
+++ b/templates.rst
@@ -1114,7 +1114,7 @@ template fragments. Configure that special URL in the ``fragments`` option:
             $framework->fragments()->path('/_fragment');
         };
 
-.. caution::
+.. warning::
 
     Embedding controllers requires making requests to those controllers and
     rendering some templates as result. This can have a significant impact on
@@ -1320,7 +1320,7 @@ different templates to create the final contents. This inheritance mechanism
 boosts your productivity because each template includes only its unique contents
 and leaves the repeated contents and HTML structure to some parent templates.
 
-.. caution::
+.. warning::
 
     When using ``extends``, a child template is forbidden to define template
     parts outside of a block. The following code throws a ``SyntaxError``:
diff --git a/testing.rst b/testing.rst
index 06360899dee..30c0e87ab77 100644
--- a/testing.rst
+++ b/testing.rst
@@ -235,7 +235,7 @@ in them, files lower in the list override previous items):
 #. ``.env.test``: overriding/setting specific test values or vars;
 #. ``.env.test.local``: overriding settings specific for this machine.
 
-.. caution::
+.. warning::
 
     The ``.env.local`` file is **not** used in the test environment, to
     make each test set-up as consistent as possible.
@@ -750,7 +750,7 @@ You can also override HTTP headers on a per request basis::
         'HTTP_USER_AGENT' => 'MySuperBrowser/1.0',
     ]);
 
-.. caution::
+.. warning::
 
     The name of your custom headers must follow the syntax defined in the
     `section 4.1.18 of RFC 3875`_: replace ``-`` by ``_``, transform it into
@@ -961,11 +961,11 @@ However, Symfony provides useful shortcut methods for the most common cases:
 Response Assertions
 ...................
 
-``assertResponseIsSuccessful(string $message = '')``
+``assertResponseIsSuccessful(string $message = '', bool $verbose = true)``
     Asserts that the response was successful (HTTP status is 2xx).
-``assertResponseStatusCodeSame(int $expectedCode, string $message = '')``
+``assertResponseStatusCodeSame(int $expectedCode, string $message = '', bool $verbose = true)``
     Asserts a specific HTTP status code.
-``assertResponseRedirects(?string $expectedLocation = null, ?int $expectedCode = null, string $message = '')``
+``assertResponseRedirects(?string $expectedLocation = null, ?int $expectedCode = null, string $message = '', bool $verbose = true)``
     Asserts the response is a redirect response (optionally, you can check
     the target location and status code). The excepted location can be either
     an absolute or a relative path.
@@ -983,9 +983,13 @@ Response Assertions
     Asserts the response format returned by the
     :method:`Symfony\\Component\\HttpFoundation\\Response::getFormat` method
     is the same as the expected value.
-``assertResponseIsUnprocessable(string $message = '')``
+``assertResponseIsUnprocessable(string $message = '', bool $verbose = true)``
     Asserts the response is unprocessable (HTTP status is 422)
 
+.. versionadded:: 7.1
+
+    The ``$verbose`` parameters were introduced in Symfony 7.1.
+
 Request Assertions
 ..................
 
diff --git a/testing/end_to_end.rst b/testing/end_to_end.rst
index e43f5fa2be2..d59f243f998 100644
--- a/testing/end_to_end.rst
+++ b/testing/end_to_end.rst
@@ -457,7 +457,7 @@ Accepting Self-Signed SSL Certificates
 To force Chrome to accept invalid and self-signed certificates, you can set the
 following environment variable: ``PANTHER_CHROME_ARGUMENTS='--ignore-certificate-errors'``.
 
-.. caution::
+.. danger::
 
     This option is insecure, use it only for testing in development environments,
     never in production (e.g. for web crawlers).
diff --git a/testing/insulating_clients.rst b/testing/insulating_clients.rst
index 5a76d517ced..ea9cba3c046 100644
--- a/testing/insulating_clients.rst
+++ b/testing/insulating_clients.rst
@@ -43,7 +43,7 @@ clean PHP process, thus avoiding any side effects.
     As an insulated client is slower, you can keep one client in the main
     process, and insulate the other ones.
 
-.. caution::
+.. warning::
 
     Insulating tests requires some serializing and unserializing operations. If
     your test includes data that can't be serialized, such as file streams when
diff --git a/translation.rst b/translation.rst
index 0e5f09d342e..2b9a3534cdc 100644
--- a/translation.rst
+++ b/translation.rst
@@ -392,7 +392,7 @@ translation of *static blocks of text*:
 
     {% trans %}Hello %name%{% endtrans %}
 
-.. caution::
+.. warning::
 
     The ``%var%`` notation of placeholders is required when translating in
     Twig templates using the tag.
@@ -410,7 +410,7 @@ You can also specify the message domain and pass some additional variables:
 
     {% trans with {'%name%': 'Fabien'} from 'app' into 'fr' %}Hello %name%{% endtrans %}
 
-.. caution::
+.. warning::
 
     Using the translation tag has the same effect as the filter, but with one
     major difference: automatic output escaping is **not** applied to translations
@@ -537,7 +537,7 @@ The choice of which loader to use is entirely up to you and is a matter of
 taste. The recommended option is to use YAML for simple projects and use XLIFF
 if you're generating translations with specialized programs or teams.
 
-.. caution::
+.. warning::
 
     Each time you create a *new* message catalog (or install a bundle
     that includes a translation catalog), be sure to clear your cache so
@@ -1175,7 +1175,7 @@ unused translation messages templates:
 
     {{ 'Symfony is great'|trans }}
 
-.. caution::
+.. warning::
 
     The extractors can't find messages translated outside templates (like form
     labels or controllers) unless using :ref:`translatable objects
diff --git a/validation.rst b/validation.rst
index 3f9b16785d1..4905283b18b 100644
--- a/validation.rst
+++ b/validation.rst
@@ -525,7 +525,7 @@ class to have at least 3 characters.
             }
         }
 
-.. caution::
+.. warning::
 
     The validator will use a value ``null`` if a typed property is uninitialized.
     This can cause unexpected behavior if the property holds a value when initialized.
diff --git a/validation/custom_constraint.rst b/validation/custom_constraint.rst
index 435b976d1d3..59da9e60568 100644
--- a/validation/custom_constraint.rst
+++ b/validation/custom_constraint.rst
@@ -62,6 +62,47 @@ You can use ``#[HasNamedArguments]`` to make some constraint options required::
         }
     }
 
+Constraint with Private Properties
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Constraints are cached for performance reasons. To achieve this, the base
+``Constraint`` class uses PHP's :phpfunction:`get_object_vars` function, which
+excludes private properties of child classes.
+
+If your constraint defines private properties, you must explicitly include them
+in the ``__sleep()`` method to ensure they are serialized correctly::
+
+    // src/Validator/ContainsAlphanumeric.php
+    namespace App\Validator;
+
+    use Symfony\Component\Validator\Attribute\HasNamedArguments;
+    use Symfony\Component\Validator\Constraint;
+
+    #[\Attribute]
+    class ContainsAlphanumeric extends Constraint
+    {
+        public string $message = 'The string "{{ string }}" contains an illegal character: it can only contain letters or numbers.';
+
+        #[HasNamedArguments]
+        public function __construct(
+            private string $mode,
+            ?array $groups = null,
+            mixed $payload = null,
+        ) {
+            parent::__construct([], $groups, $payload);
+        }
+
+        public function __sleep(): array
+        {
+            return array_merge(
+                parent::__sleep(),
+                [
+                    'mode'
+                ]
+            );
+        }
+    }
+
 Creating the Validator itself
 -----------------------------
 
diff --git a/validation/groups.rst b/validation/groups.rst
index 3842c781969..8d84e52c0da 100644
--- a/validation/groups.rst
+++ b/validation/groups.rst
@@ -140,7 +140,7 @@ Constraints in the ``Default`` group of a class are the constraints that have
 either no explicit group configured or that are configured to a group equal to
 the class name or the string ``Default``.
 
-.. caution::
+.. warning::
 
     When validating *just* the User object, there is no difference between the
     ``Default`` group and the ``User`` group. But, there is a difference if
diff --git a/validation/sequence_provider.rst b/validation/sequence_provider.rst
index 7d3663f45fc..836568c2327 100644
--- a/validation/sequence_provider.rst
+++ b/validation/sequence_provider.rst
@@ -117,7 +117,7 @@ In this example, it will first validate all constraints in the group ``User``
 (which is the same as the ``Default`` group). Only if all constraints in
 that group are valid, the second group, ``Strict``, will be validated.
 
-.. caution::
+.. warning::
 
     As you have already seen in :doc:`/validation/groups`, the ``Default`` group
     and the group containing the class name (e.g. ``User``) were identical.
@@ -131,7 +131,7 @@ that group are valid, the second group, ``Strict``, will be validated.
     sequence, which will contain the ``Default`` group which references the
     same group sequence, ...).
 
-.. caution::
+.. warning::
 
     Calling ``validate()`` with a group in the sequence (``Strict`` in previous
     example) will cause a validation **only** with that group and not with all
diff --git a/web_link.rst b/web_link.rst
index e5ad7e1159c..8602445313f 100644
--- a/web_link.rst
+++ b/web_link.rst
@@ -50,20 +50,14 @@ Imagine that your application includes a web page like this:
     </body>
     </html>
 
-Following the traditional HTTP workflow, when this page is served browsers will
-make one request for the HTML page and another request for the linked CSS file.
-However, thanks to HTTP/2 your application can start sending the CSS file
-contents even before browsers request them.
-
-To do that, first install the WebLink component:
-
-.. code-block:: terminal
-
-    $ composer require symfony/web-link
-
-Now, update the template to use the ``preload()`` Twig function provided by
-WebLink. The `"as" attribute`_ is mandatory because browsers need it to apply
-correct prioritization and the content security policy:
+In a traditional HTTP workflow, when this page is loaded, browsers make one
+request for the HTML document and another for the linked CSS file. However,
+with HTTP/2, your application can send the CSS file's contents to the browser
+before it requests them.
+
+To achieve this, update your template to use the ``preload()`` Twig function
+provided by WebLink. Note that the `"as" attribute`_ is required, as browsers use
+it to prioritize resources correctly and comply with the content security policy:
 
 .. code-block:: html+twig
 
diff --git a/webhook.rst b/webhook.rst
index aba95cffb04..674c9f2c5c6 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -23,6 +23,7 @@ Currently, the following third-party mailer providers support webhooks:
 ============== ============================================
 Mailer Service Parser service name
 ============== ============================================
+AhaSend        ``mailer.webhook.request_parser.ahasend``
 Brevo          ``mailer.webhook.request_parser.brevo``
 Mandrill       ``mailer.webhook.request_parser.mailchimp``
 MailerSend     ``mailer.webhook.request_parser.mailersend``
@@ -42,9 +43,13 @@ Sweego         ``mailer.webhook.request_parser.sweego``
 
 .. versionadded:: 7.2
 
-    The ``Mandrill``,  ``Mailomat``, ``Mailtrap``, and ``Sweego`` integrations were introduced in
+    The ``Mandrill``, ``Mailomat``, ``Mailtrap``, and ``Sweego`` integrations were introduced in
     Symfony 7.2.
 
+.. versionadded:: 7.3
+
+    The ``AhaSend`` integration was introduced in Symfony 7.3.
+
 .. note::
 
     Install the third-party mailer provider you want to use as described in the
diff --git a/workflow.rst b/workflow.rst
index 52997531409..11b4005bb10 100644
--- a/workflow.rst
+++ b/workflow.rst
@@ -321,7 +321,7 @@ if you are using Doctrine, the matching column definition should use the type ``
         // ...
     }
 
-.. caution::
+.. warning::
 
     You should not use the type ``simple_array`` for your marking store. Inside
     a multiple state marking store, places are stored as keys with a value of one,

From f9046f9abf1d47145d29d592f36fdad7f3db3a56 Mon Sep 17 00:00:00 2001
From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com>
Date: Fri, 17 Jan 2025 10:30:22 +0100
Subject: [PATCH 488/747] docs: add OIDC Discovery documentation

---
 security/access_token.rst | 145 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 145 insertions(+)

diff --git a/security/access_token.rst b/security/access_token.rst
index c0ff4692676..0370949e584 100644
--- a/security/access_token.rst
+++ b/security/access_token.rst
@@ -411,6 +411,72 @@ and retrieve the user info:
             ;
         };
 
+To enable the `OpenID Connect Discovery`_, the ``OidcUserInfoTokenHandler``
+requires the ``symfony/cache`` package to store the OIDC configuration in
+cache. If you haven't installed it yet, run this command:
+
+.. code-block:: terminal
+
+    $ composer require symfony/cache
+
+Then, configure the ``base_uri`` and ``discovery`` keys:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/security.yaml
+        security:
+            firewalls:
+                main:
+                    access_token:
+                        token_handler:
+                            oidc_user_info:
+                                base_uri: https://www.example.com/realms/demo/
+                                discovery:
+                                    cache: cache.app
+
+    .. code-block:: xml
+
+        <!-- config/packages/security.xml -->
+        <?xml version="1.0" encoding="UTF-8"?>
+        <srv:container xmlns="http://symfony.com/schema/dic/security"
+            xmlns:srv="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                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">
+
+            <config>
+                <firewall name="main">
+                    <access-token>
+                        <token-handler>
+                            <oidc-user-info base-uri="https://www.example.com/realms/demo/">
+                                <discovery cache="cache.app"/>
+                            </oidc-user-info>
+                        </token-handler>
+                    </access-token>
+                </firewall>
+            </config>
+        </srv:container>
+
+    .. code-block:: php
+
+        // config/packages/security.php
+        use Symfony\Config\SecurityConfig;
+
+        return static function (SecurityConfig $security) {
+            $security->firewall('main')
+                ->accessToken()
+                    ->tokenHandler()
+                        ->oidcUserInfo()
+                            ->baseUri('https://www.example.com/realms/demo/')
+                            ->discovery()
+                                ->cache('cache.app')
+            ;
+        };
+
 Following the `OpenID Connect Specification`_, the ``sub`` claim is used as user
 identifier by default. To use another claim, specify it on the configuration:
 
@@ -625,6 +691,84 @@ it and retrieve the user info from it:
     The support of multiple algorithms to sign the JWS was introduced in Symfony 7.1.
     In previous versions, only the ``ES256`` algorithm was supported.
 
+To enable the `OpenID Connect Discovery`_, the ``OidcTokenHandler``
+requires the ``symfony/cache`` package to store the OIDC configuration in
+cache. If you haven't installed it yet, run this command:
+
+.. code-block:: terminal
+
+    $ composer require symfony/cache
+
+Then, you can remove the ``keyset`` configuration key (it will be imported from
+the OpenID Connect Discovery), and configure the ``discovery`` key:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/security.yaml
+        security:
+            firewalls:
+                main:
+                    access_token:
+                        token_handler:
+                            oidc:
+                                claim: email
+                                algorithms: ['ES256', 'RS256']
+                                audience: 'api-example'
+                                issuers: ['https://oidc.example.com']
+                                discovery:
+                                    base_uri: https://www.example.com/realms/demo/
+                                    cache: cache.app
+
+    .. code-block:: xml
+
+        <!-- config/packages/security.xml -->
+        <?xml version="1.0" encoding="UTF-8"?>
+        <srv:container xmlns="http://symfony.com/schema/dic/security"
+            xmlns:srv="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                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">
+
+            <config>
+                <firewall name="main">
+                    <access-token>
+                        <token-handler>
+                            <oidc claim="email" audience="api-example">
+                                <algorithm>ES256</algorithm>
+                                <algorithm>RS256</algorithm>
+                                <issuer>https://oidc.example.com</issuer>
+                                <discovery base-uri="https://www.example.com/realms/demo/" cache="cache.app">
+                            </oidc>
+                        </token-handler>
+                    </access-token>
+                </firewall>
+            </config>
+        </srv:container>
+
+    .. code-block:: php
+
+        // config/packages/security.php
+        use Symfony\Config\SecurityConfig;
+
+        return static function (SecurityConfig $security) {
+            $security->firewall('main')
+                ->accessToken()
+                    ->tokenHandler()
+                        ->oidc()
+                            ->claim('email')
+                            ->algorithms(['ES256', 'RS256'])
+                            ->audience('api-example')
+                            ->issuers(['https://oidc.example.com'])
+                            ->discovery()
+                                ->baseUri('https://www.example.com/realms/demo/')
+                                ->cache('cache.app')
+            ;
+        };
+
 Following the `OpenID Connect Specification`_, the ``sub`` claim is used by
 default as user identifier. To use another claim, specify it on the
 configuration:
@@ -925,5 +1069,6 @@ for :ref:`stateless firewalls <reference-security-stateless>`.
 .. _`JSON Web Tokens (JWT)`: https://datatracker.ietf.org/doc/html/rfc7519
 .. _`OpenID Connect (OIDC)`: https://en.wikipedia.org/wiki/OpenID#OpenID_Connect_(OIDC)
 .. _`OpenID Connect Specification`: https://openid.net/specs/openid-connect-core-1_0.html
+.. _`OpenID Connect Discovery`: https://openid.net/specs/openid-connect-discovery-1_0.html
 .. _`RFC6750`: https://datatracker.ietf.org/doc/html/rfc6750
 .. _`SAML2 (XML structures)`: https://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html

From 3c1398a9248f3cf538c9ff40c603e8ebb3ba695a Mon Sep 17 00:00:00 2001
From: Christopher Hertel <mail@christopher-hertel.de>
Date: Fri, 17 Jan 2025 17:15:32 +0100
Subject: [PATCH 489/747] docs: web profiler ajax_replace

---
 profiler.rst                             | 61 +++++++++++++++++-------
 reference/configuration/web_profiler.rst | 13 +++++
 2 files changed, 58 insertions(+), 16 deletions(-)

diff --git a/profiler.rst b/profiler.rst
index 57d412472ba..7fc97c8ee33 100644
--- a/profiler.rst
+++ b/profiler.rst
@@ -217,9 +217,48 @@ user by dynamically rewriting the current page rather than loading entire new
 pages from a server.
 
 By default, the debug toolbar displays the information of the initial page load
-and doesn't refresh after each AJAX request. However, you can set the
-``Symfony-Debug-Toolbar-Replace`` header to a value of ``'1'`` in the response to
-the AJAX request to force the refresh of the toolbar::
+and doesn't refresh after each AJAX request. However, you can configure the
+toolbar to be refreshed after each AJAX request by enabling ``ajax_replace`` in the
+``web_profiler`` configuration:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/web_profiler.yaml
+        web_profiler:
+            toolbar:
+                ajax_replace: true
+
+    .. code-block:: xml
+
+        <!-- config/packages/web_profiler.xml -->
+        <?xml version="1.0" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xmlns:web-profiler="http://symfony.com/schema/dic/webprofiler"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+                <web-profiler:config>
+                    <web-profiler:toolbar ajax-replace="true"/>
+                </web-profiler:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/web_profiler.php
+        use Symfony\Config\WebProfilerConfig;
+
+        return static function (WebProfilerConfig $profiler): void {
+            $profiler->toolbar()
+                ->ajaxReplace(true);
+        };
+
+If you need a more sophisticated solution, you can set the
+``Symfony-Debug-Toolbar-Replace`` header to a value of ``'1'`` in the response
+yourself::
 
     $response->headers->set('Symfony-Debug-Toolbar-Replace', '1');
 
@@ -228,31 +267,21 @@ production. To do that, create an :doc:`event subscriber </event_dispatcher>`
 and listen to the :ref:`kernel.response <component-http-kernel-kernel-response>`
 event::
 
+    use Symfony\Component\DependencyInjection\Attribute\When;
     use Symfony\Component\EventDispatcher\EventSubscriberInterface;
     use Symfony\Component\HttpKernel\Event\ResponseEvent;
     use Symfony\Component\HttpKernel\KernelInterface;
 
     // ...
 
+    #[When(env: 'dev')]
     class MySubscriber implements EventSubscriberInterface
     {
-        public function __construct(
-            private KernelInterface $kernel,
-        ) {
-        }
-
         // ...
 
         public function onKernelResponse(ResponseEvent $event): void
         {
-            if (!$this->kernel->isDebug()) {
-                return;
-            }
-
-            $request = $event->getRequest();
-            if (!$request->isXmlHttpRequest()) {
-                return;
-            }
+            // Your custom logic here
 
             $response = $event->getResponse();
             $response->headers->set('Symfony-Debug-Toolbar-Replace', '1');
diff --git a/reference/configuration/web_profiler.rst b/reference/configuration/web_profiler.rst
index 93c65621999..9eda76d5523 100644
--- a/reference/configuration/web_profiler.rst
+++ b/reference/configuration/web_profiler.rst
@@ -56,8 +56,21 @@ on the given link to perform the redirect.
 toolbar
 ~~~~~~~
 
+enabled
+.......
 **type**: ``boolean`` **default**: ``false``
 
 It enables and disables the toolbar entirely. Usually you set this to ``true``
 in the ``dev`` and ``test`` environments and to ``false`` in the ``prod``
 environment.
+
+ajax_replace
+............
+**type**: ``boolean`` **default**: ``false``
+
+If you set this option to ``true``, the toolbar is replaced on AJAX requests.
+This only works in combination with an enabled toolbar.
+
+.. versionadded:: 7.3
+
+    The ``ajax_replace`` configuration option was introduced in Symfony 7.3.

From 0c3c3127057533a0fdd130fb609206112c9bf098 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Sat, 18 Jan 2025 09:38:04 +0100
Subject: [PATCH 490/747] replace versionadded with deprecated directive

---
 service_container/debug.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/service_container/debug.rst b/service_container/debug.rst
index aab6fa9529f..9e3e28a5343 100644
--- a/service_container/debug.rst
+++ b/service_container/debug.rst
@@ -52,7 +52,7 @@ its id:
 
     $ php bin/console debug:container App\Service\Mailer
 
-.. versionadded:: 7.3
+.. deprecated:: 7.3
 
     Starting in Symfony 7.3, this command displays the service arguments by default.
     In earlier Symfony versions, you needed to use the ``--show-arguments`` option,

From 57888616b65a5d6a219a679a9190a65812266675 Mon Sep 17 00:00:00 2001
From: Wouter Ras <wouter@quilius.nl>
Date: Fri, 17 Jan 2025 15:05:41 +0100
Subject: [PATCH 491/747] [Mailer] [Smtp] Add source_ip option

---
 mailer.rst | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/mailer.rst b/mailer.rst
index e5d646d5aa2..e2204d00db0 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -426,6 +426,27 @@ setting the ``auto_tls`` option to ``false`` in the DSN::
 
     This setting only works when the ``smtp://`` protocol is used.
 
+Binding to IPv4 or IPv6
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 7.3
+
+    The option to bind to IPv4 or IPv6 or a specific IP address was introduced in Symfony 7.3.
+
+By default, the underlying SocketStream will bind to IPv4 or IPv6 depending on the available
+interfaces. By specifying the ``source_ip`` option, binding to either IPv4 or IPv6 can be enforced,
+or even to a specific address. To bind to IPv4, use::
+
+    $dsn = 'smtp://smtp.example.com?source_ip=0.0.0.0';
+
+As per RFC2732, IPv6 addresses must be surrounded by square brackets. To bind to IPv6, use::
+
+    $dsn = 'smtp://smtp.example.com?source_ip=[::]';
+
+.. note::
+
+    This setting only works when the ``smtp://`` protocol is used.
+
 Overriding default SMTP authenticators
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From ba6944a1851e02385ab48ad778b32569e2a19f83 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 20 Jan 2025 10:33:49 +0100
Subject: [PATCH 492/747] Minor tweaks

---
 mailer.rst | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index e2204d00db0..17828f18be2 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -431,21 +431,21 @@ Binding to IPv4 or IPv6
 
 .. versionadded:: 7.3
 
-    The option to bind to IPv4 or IPv6 or a specific IP address was introduced in Symfony 7.3.
+    The option to bind to IPv4, or IPv6, or a specific IP address was introduced in Symfony 7.3.
 
-By default, the underlying SocketStream will bind to IPv4 or IPv6 depending on the available
-interfaces. By specifying the ``source_ip`` option, binding to either IPv4 or IPv6 can be enforced,
-or even to a specific address. To bind to IPv4, use::
+By default, the underlying ``SocketStream`` will bind to IPv4 or IPv6 based on the
+available interfaces. You can enforce binding to a specific protocol or IP address
+by using the ``source_ip`` option. To bind to IPv4, use::
 
     $dsn = 'smtp://smtp.example.com?source_ip=0.0.0.0';
 
-As per RFC2732, IPv6 addresses must be surrounded by square brackets. To bind to IPv6, use::
+As per RFC2732, IPv6 addresses must be enclosed in square brackets. To bind to IPv6, use::
 
     $dsn = 'smtp://smtp.example.com?source_ip=[::]';
 
 .. note::
 
-    This setting only works when the ``smtp://`` protocol is used.
+    This option only works when using the ``smtp://`` protocol.
 
 Overriding default SMTP authenticators
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

From 0776cba27ef9aeed25406477e7c6a8c19425164d Mon Sep 17 00:00:00 2001
From: Quentin Dequippe <quentin.dequippe@tiime.fr>
Date: Mon, 28 Oct 2024 18:41:54 +0400
Subject: [PATCH 493/747] [Serializer] Documentation for xml empty attribute

---
 serializer/encoders.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/serializer/encoders.rst b/serializer/encoders.rst
index d5a98356156..2e5c0e6e66a 100644
--- a/serializer/encoders.rst
+++ b/serializer/encoders.rst
@@ -205,11 +205,16 @@ These are the options available on the :ref:`serializer context <serializer-cont
 ``cdata_wrapping_pattern`` (default: ````/[<>&]/````)
     A regular expression pattern to determine if a value should be wrapped
     in a CDATA section.
+``ignore_empty_attributes`` (default: ``false``)
+    If set to true, ignores all attributes with empty values in the generated XML
 
 .. versionadded:: 7.1
 
     The ``cdata_wrapping_pattern`` option was introduced in Symfony 7.1.
 
+.. versionadded:: 7.3
+
+    The ``ignore_empty_attributes`` option was introduced in Symfony 7.3.
 
 Example with a custom ``context``::
 

From 141c65cd756145c43542211e5963a01bb690396f Mon Sep 17 00:00:00 2001
From: alanzarli <azarli@smsbox.fr>
Date: Tue, 21 Jan 2025 10:57:32 +0100
Subject: [PATCH 494/747] [Notifier][Webhook]Add Smsbox Notifier doc

---
 notifier.rst | 2 +-
 webhook.rst  | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/notifier.rst b/notifier.rst
index 090f4db2007..30565f45b2c 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -177,7 +177,7 @@ Service
                     **Webhook support**: No
 `Smsbox`_           **Install**: ``composer require symfony/smsbox-notifier`` \
                     **DSN**: ``smsbox://APIKEY@default?mode=MODE&strategy=STRATEGY&sender=SENDER`` \
-                    **Webhook support**: No
+                    **Webhook support**: Yes
 `SmsBiuras`_        **Install**: ``composer require symfony/sms-biuras-notifier`` \
                     **DSN**: ``smsbiuras://UID:API_KEY@default?from=FROM&test_mode=0`` \
                     **Webhook support**: No
diff --git a/webhook.rst b/webhook.rst
index 674c9f2c5c6..6c5d46a956a 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -171,6 +171,7 @@ Currently, the following third-party SMS transports support webhooks:
 SMS service  Parser service name
 ============ ==========================================
 Twilio       ``notifier.webhook.request_parser.twilio``
+Smsbox       ``notifier.webhook.request_parser.smsbox``
 Sweego       ``notifier.webhook.request_parser.sweego``
 Vonage       ``notifier.webhook.request_parser.vonage``
 ============ ==========================================

From 12bb604aac1f3a00871dc9d99042f7a6d3abea53 Mon Sep 17 00:00:00 2001
From: gr8b <grb8.github@gmail.com>
Date: Sat, 4 Jan 2025 17:49:29 +0200
Subject: [PATCH 495/747] [Yaml] feature #59315  Add compact nested mapping
 support to Dumper

---
 components/yaml.rst | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/components/yaml.rst b/components/yaml.rst
index 30f715a7a24..c373c98015d 100644
--- a/components/yaml.rst
+++ b/components/yaml.rst
@@ -440,6 +440,34 @@ By default, digit-only array keys are dumped as integers. You can use the
     $dumped = Yaml::dump([200 => 'foo'], 2, 4, Yaml::DUMP_NUMERIC_KEY_AS_STRING);
     // '200': foo
 
+Dumping Collection of Maps
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, the collection of maps uses a hyphen on a separate line as a delimiter.
+To use the delimiter line as part of the map dump, use the ``Yaml::DUMP_COMPACT_NESTED_MAPPING`` flag.
+
+Dump without flag set:
+
+.. code-block:: yaml
+
+    planets:
+      -
+        name: Mercury
+        distance: 57910000
+      -
+        name: Jupiter
+        distance: 778500000
+
+Dump with ``Yaml::DUMP_COMPACT_NESTED_MAPPING`` flag set:
+
+.. code-block:: yaml
+
+    planets:
+      - name: Mercury
+        distance: 57910000
+      - name: Jupiter
+        distance: 778500000
+
 Syntax Validation
 ~~~~~~~~~~~~~~~~~
 

From 05aacc296c26990446b86752bf157145b051f760 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 22 Jan 2025 08:38:02 +0100
Subject: [PATCH 496/747] Minor tweaks

---
 components/yaml.rst | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/components/yaml.rst b/components/yaml.rst
index aea0b6437bd..40a172f334d 100644
--- a/components/yaml.rst
+++ b/components/yaml.rst
@@ -453,10 +453,8 @@ By default, digit-only array keys are dumped as integers. You can use the
 Dumping Collection of Maps
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-By default, the collection of maps uses a hyphen on a separate line as a delimiter.
-To use the delimiter line as part of the map dump, use the ``Yaml::DUMP_COMPACT_NESTED_MAPPING`` flag.
-
-Dump without flag set:
+When the YAML component dumps collections of maps, it uses a hyphen on a separate
+line as a delimiter:
 
 .. code-block:: yaml
 
@@ -468,7 +466,8 @@ Dump without flag set:
         name: Jupiter
         distance: 778500000
 
-Dump with ``Yaml::DUMP_COMPACT_NESTED_MAPPING`` flag set:
+To produce a more compact output where the delimiter is included within the map,
+use the ``Yaml::DUMP_COMPACT_NESTED_MAPPING`` flag:
 
 .. code-block:: yaml
 
@@ -478,6 +477,10 @@ Dump with ``Yaml::DUMP_COMPACT_NESTED_MAPPING`` flag set:
       - name: Jupiter
         distance: 778500000
 
+.. versionadded:: 7.3
+
+    The ``Yaml::DUMP_COMPACT_NESTED_MAPPING`` flag was introduced in Symfony 7.3.
+
 Syntax Validation
 ~~~~~~~~~~~~~~~~~
 

From a00dddbdd82e84c84387f536cac06ca7f0027de1 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Fri, 24 Jan 2025 11:36:59 +0100
Subject: [PATCH 497/747] use named-arguments to configure validation
 constraint options

---
 components/console/helpers/questionhelper.rst |   8 +-
 components/options_resolver.rst               |   2 +-
 components/validator.rst                      |   2 +-
 components/validator/metadata.rst             |   8 +-
 components/validator/resources.rst            |   8 +-
 controller/upload_file.rst                    |  10 +-
 form/without_class.rst                        |   8 +-
 reference/constraints/All.rst                 |  10 +-
 reference/constraints/AtLeastOneOf.rst        |  26 ++---
 reference/constraints/Callback.rst            |   2 +-
 reference/constraints/CardScheme.rst          |  10 +-
 reference/constraints/Choice.rst              |  22 ++--
 reference/constraints/Collection.rst          |  46 ++++----
 reference/constraints/Compound.rst            |   4 +-
 reference/constraints/Count.rst               |  12 +--
 reference/constraints/CssColor.rst            |  18 ++--
 reference/constraints/DivisibleBy.rst         |   6 +-
 reference/constraints/Email.rst               |   6 +-
 reference/constraints/EqualTo.rst             |   6 +-
 reference/constraints/Expression.rst          |  26 ++---
 reference/constraints/ExpressionSyntax.rst    |   6 +-
 reference/constraints/File.rst                |  10 +-
 reference/constraints/GreaterThan.rst         |   6 +-
 reference/constraints/GreaterThanOrEqual.rst  |   6 +-
 reference/constraints/Hostname.rst            |   6 +-
 reference/constraints/Iban.rst                |   6 +-
 reference/constraints/IdenticalTo.rst         |   6 +-
 reference/constraints/Image.rst               |  20 ++--
 reference/constraints/IsFalse.rst             |   6 +-
 reference/constraints/IsTrue.rst              |   6 +-
 reference/constraints/Isbn.rst                |   8 +-
 reference/constraints/Json.rst                |   6 +-
 reference/constraints/Length.rst              |  12 +--
 reference/constraints/LessThan.rst            |   6 +-
 reference/constraints/LessThanOrEqual.rst     |   6 +-
 reference/constraints/Locale.rst              |   6 +-
 reference/constraints/Luhn.rst                |   6 +-
 reference/constraints/NotEqualTo.rst          |   6 +-
 reference/constraints/NotIdenticalTo.rst      |   6 +-
 reference/constraints/PasswordStrength.rst    |  12 +--
 reference/constraints/Range.rst               |  34 +++---
 reference/constraints/Regex.rst               |  26 ++---
 reference/constraints/Sequentially.rst        |   4 +-
 reference/constraints/Type.rst                |  18 ++--
 reference/constraints/Unique.rst              |   6 +-
 reference/constraints/UniqueEntity.rst        |  16 +--
 reference/constraints/Url.rst                 |  26 ++---
 reference/constraints/Valid.rst               |   4 +-
 reference/constraints/Week.rst                |   8 +-
 reference/constraints/When.rst                |  24 ++---
 reference/constraints/WordCount.rst           |   8 +-
 reference/constraints/Yaml.rst                |  14 +--
 .../_comparison-value-option.rst.inc          |   2 +-
 validation.rst                                | 102 ++----------------
 validation/custom_constraint.rst              |  12 ++-
 validation/groups.rst                         |  30 +++---
 validation/sequence_provider.rst              |  16 +--
 validation/severity.rst                       |  18 ++--
 validation/translations.rst                   |  10 +-
 59 files changed, 343 insertions(+), 427 deletions(-)

diff --git a/components/console/helpers/questionhelper.rst b/components/console/helpers/questionhelper.rst
index 3dc97d5c0d3..c7e064b16ca 100644
--- a/components/console/helpers/questionhelper.rst
+++ b/components/console/helpers/questionhelper.rst
@@ -480,10 +480,10 @@ invalid answer and will only be able to proceed if their input is valid.
         use Symfony\Component\Validator\Validation;
 
         $question = new Question('Please enter the name of the bundle', 'AcmeDemoBundle');
-        $validation = Validation::createCallable(new Regex([
-            'pattern' => '/^[a-zA-Z]+Bundle$/',
-            'message' => 'The name of the bundle should be suffixed with \'Bundle\'',
-        ]));
+        $validation = Validation::createCallable(new Regex(
+            pattern: '/^[a-zA-Z]+Bundle$/',
+            message: 'The name of the bundle should be suffixed with \'Bundle\'',
+        ));
         $question->setValidator($validation);
 
 Validating a Hidden Response
diff --git a/components/options_resolver.rst b/components/options_resolver.rst
index 95741a7e372..65685106c13 100644
--- a/components/options_resolver.rst
+++ b/components/options_resolver.rst
@@ -394,7 +394,7 @@ returns ``true`` for acceptable values and ``false`` for invalid values::
 
         // ...
         $resolver->setAllowedValues('transport', Validation::createIsValidCallable(
-            new Length(['min' => 10 ])
+            new Length(min: 10)
         ));
 
 In sub-classes, you can use :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::addAllowedValues`
diff --git a/components/validator.rst b/components/validator.rst
index 085c77a7946..12c61507257 100644
--- a/components/validator.rst
+++ b/components/validator.rst
@@ -36,7 +36,7 @@ characters long::
 
     $validator = Validation::createValidator();
     $violations = $validator->validate('Bernhard', [
-        new Length(['min' => 10]),
+        new Length(min: 10),
         new NotBlank(),
     ]);
 
diff --git a/components/validator/metadata.rst b/components/validator/metadata.rst
index e7df42413bc..782e1ee216f 100755
--- a/components/validator/metadata.rst
+++ b/components/validator/metadata.rst
@@ -24,7 +24,7 @@ the ``Author`` class has at least 3 characters::
             $metadata->addPropertyConstraint('firstName', new Assert\NotBlank());
             $metadata->addPropertyConstraint(
                 'firstName',
-                new Assert\Length(["min" => 3])
+                new Assert\Length(min: 3)
             );
         }
     }
@@ -55,9 +55,9 @@ Then, add the Validator component configuration to the class::
     {
         public static function loadValidatorMetadata(ClassMetadata $metadata): void
         {
-            $metadata->addGetterConstraint('passwordSafe', new Assert\IsTrue([
-                'message' => 'The password cannot match your first name',
-            ]));
+            $metadata->addGetterConstraint('passwordSafe', new Assert\IsTrue(
+                message: 'The password cannot match your first name',
+            ));
         }
     }
 
diff --git a/components/validator/resources.rst b/components/validator/resources.rst
index 5b1448dfba1..64bf26e44d5 100644
--- a/components/validator/resources.rst
+++ b/components/validator/resources.rst
@@ -42,10 +42,10 @@ In this example, the validation metadata is retrieved executing the
         public static function loadValidatorMetadata(ClassMetadata $metadata): void
         {
             $metadata->addPropertyConstraint('name', new Assert\NotBlank());
-            $metadata->addPropertyConstraint('name', new Assert\Length([
-                'min' => 5,
-                'max' => 20,
-            ]));
+            $metadata->addPropertyConstraint('name', new Assert\Length(
+                min: 5,
+                max: 20,
+            ));
         }
     }
 
diff --git a/controller/upload_file.rst b/controller/upload_file.rst
index b3dc2d6ffd0..cff326a8e2b 100644
--- a/controller/upload_file.rst
+++ b/controller/upload_file.rst
@@ -75,14 +75,14 @@ so Symfony doesn't try to get/set its value from the related entity::
                     // unmapped fields can't define their validation using attributes
                     // in the associated entity, so you can use the PHP constraint classes
                     'constraints' => [
-                        new File([
-                            'maxSize' => '1024k',
-                            'mimeTypes' => [
+                        new File(
+                            maxSize: '1024k',
+                            mimeTypes: [
                                 'application/pdf',
                                 'application/x-pdf',
                             ],
-                            'mimeTypesMessage' => 'Please upload a valid PDF document',
-                        ])
+                            mimeTypesMessage: 'Please upload a valid PDF document',
+                        )
                     ],
                 ])
                 // ...
diff --git a/form/without_class.rst b/form/without_class.rst
index 8b0af7cf23f..5fec7f3a663 100644
--- a/form/without_class.rst
+++ b/form/without_class.rst
@@ -96,12 +96,12 @@ but here's a short example::
     {
         $builder
             ->add('firstName', TextType::class, [
-                'constraints' => new Length(['min' => 3]),
+                'constraints' => new Length(min: 3),
             ])
             ->add('lastName', TextType::class, [
                 'constraints' => [
                     new NotBlank(),
-                    new Length(['min' => 3]),
+                    new Length(min: 3),
                 ],
             ])
         ;
@@ -153,10 +153,10 @@ This can be done by setting the ``constraints`` option in the
         $resolver->setDefaults([
             'data_class' => null,
             'constraints' => new Collection([
-                'firstName' => new Length(['min' => 3]),
+                'firstName' => new Length(min: 3),
                 'lastName' => [
                     new NotBlank(),
-                    new Length(['min' => 3]),
+                    new Length(min: 3),
                 ],
             ]),
         ]);
diff --git a/reference/constraints/All.rst b/reference/constraints/All.rst
index 3aa05b1d2d0..43ff4d6ac9d 100644
--- a/reference/constraints/All.rst
+++ b/reference/constraints/All.rst
@@ -79,12 +79,12 @@ entry in that array:
         {
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('favoriteColors', new Assert\All([
-                    'constraints' => [
+                $metadata->addPropertyConstraint('favoriteColors', new Assert\All(
+                    constraints: [
                         new Assert\NotBlank(),
-                        new Assert\Length(['min' => 5]),
+                        new Assert\Length(min: 5),
                     ],
-                ]));
+                ));
             }
         }
 
@@ -97,7 +97,7 @@ Options
 ``constraints``
 ~~~~~~~~~~~~~~~
 
-**type**: ``array`` [:ref:`default option <validation-default-option>`]
+**type**: ``array``
 
 This required option is the array of validation constraints that you want
 to apply to each element of the underlying array.
diff --git a/reference/constraints/AtLeastOneOf.rst b/reference/constraints/AtLeastOneOf.rst
index 0a6ab618aa5..fecbe617f5a 100644
--- a/reference/constraints/AtLeastOneOf.rst
+++ b/reference/constraints/AtLeastOneOf.rst
@@ -115,23 +115,23 @@ The following constraints ensure that:
         {
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('password', new Assert\AtLeastOneOf([
-                    'constraints' => [
-                        new Assert\Regex(['pattern' => '/#/']),
-                        new Assert\Length(['min' => 10]),
+                $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' => [
+                $metadata->addPropertyConstraint('grades', new Assert\AtLeastOneOf(
+                    constraints: [
+                        new Assert\Count(min: 3),
+                        new Assert\All(
+                            constraints: [
                                 new Assert\GreaterThanOrEqual(5),
                             ],
-                        ]),
+                        ),
                     ],
-                ]));
+                ));
             }
         }
 
@@ -141,7 +141,7 @@ Options
 constraints
 ~~~~~~~~~~~
 
-**type**: ``array`` [:ref:`default option <validation-default-option>`]
+**type**: ``array``
 
 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.
diff --git a/reference/constraints/Callback.rst b/reference/constraints/Callback.rst
index f4c78a9642a..017b9435cff 100644
--- a/reference/constraints/Callback.rst
+++ b/reference/constraints/Callback.rst
@@ -259,7 +259,7 @@ Options
 ``callback``
 ~~~~~~~~~~~~
 
-**type**: ``string``, ``array`` or ``Closure`` [:ref:`default option <validation-default-option>`]
+**type**: ``string``, ``array`` or ``Closure``
 
 The callback option accepts three different formats for specifying the
 callback method:
diff --git a/reference/constraints/CardScheme.rst b/reference/constraints/CardScheme.rst
index 6e98e6fab98..a2ed9c568c3 100644
--- a/reference/constraints/CardScheme.rst
+++ b/reference/constraints/CardScheme.rst
@@ -77,12 +77,12 @@ on an object that will contain a credit card number.
         {
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('cardNumber', new Assert\CardScheme([
-                    'schemes' => [
+                $metadata->addPropertyConstraint('cardNumber', new Assert\CardScheme(
+                    schemes: [
                         Assert\CardScheme::VISA,
                     ],
-                    'message' => 'Your credit card number is invalid.',
-                ]));
+                    message: 'Your credit card number is invalid.',
+                ));
             }
         }
 
@@ -114,7 +114,7 @@ Parameter        Description
 ``schemes``
 ~~~~~~~~~~~
 
-**type**: ``mixed`` [:ref:`default option <validation-default-option>`]
+**type**: ``mixed``
 
 This option is required and represents the name of the number scheme used
 to validate the credit card number, it can either be a string or an array.
diff --git a/reference/constraints/Choice.rst b/reference/constraints/Choice.rst
index 5a9c365be37..cdf6b6e47fd 100644
--- a/reference/constraints/Choice.rst
+++ b/reference/constraints/Choice.rst
@@ -100,10 +100,10 @@ If your valid choice list is simple, you can pass them in directly via the
                     new Assert\Choice(['New York', 'Berlin', 'Tokyo'])
                 );
 
-                $metadata->addPropertyConstraint('genre', new Assert\Choice([
-                    'choices' => ['fiction', 'non-fiction'],
-                    'message' => 'Choose a valid genre.',
-                ]));
+                $metadata->addPropertyConstraint('genre', new Assert\Choice(
+                    choices: ['fiction', 'non-fiction'],
+                    message: 'Choose a valid genre.',
+                ));
             }
         }
 
@@ -182,9 +182,9 @@ constraint.
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('genre', new Assert\Choice([
-                    'callback' => 'getGenres',
-                ]));
+                $metadata->addPropertyConstraint('genre', new Assert\Choice(
+                    callback: 'getGenres',
+                ));
             }
         }
 
@@ -250,9 +250,9 @@ you can pass the class name and the method as an array.
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('genre', new Assert\Choice([
-                    'callback' => [Genre::class, 'getGenres'],
-                ]));
+                $metadata->addPropertyConstraint('genre', new Assert\Choice(
+                    callback: [Genre::class, 'getGenres'],
+                ));
             }
         }
 
@@ -271,7 +271,7 @@ to return the choices array. See
 ``choices``
 ~~~~~~~~~~~
 
-**type**: ``array`` [:ref:`default option <validation-default-option>`]
+**type**: ``array``
 
 A required option (unless `callback`_ is specified) - this is the array
 of options that should be considered in the valid set. The input value
diff --git a/reference/constraints/Collection.rst b/reference/constraints/Collection.rst
index 2d16d201b17..c35a0103581 100644
--- a/reference/constraints/Collection.rst
+++ b/reference/constraints/Collection.rst
@@ -139,8 +139,8 @@ following:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('profileData', new Assert\Collection([
-                    'fields' => [
+                $metadata->addPropertyConstraint('profileData', new Assert\Collection(
+                    fields: [
                         'personal_email' => new Assert\Email(),
                         'short_bio' => [
                             new Assert\NotBlank(),
@@ -150,8 +150,8 @@ following:
                             ]),
                         ],
                     ],
-                    'allowMissingFields' => true,
-                ]));
+                    allowMissingFields: true,
+                ));
             }
         }
 
@@ -267,15 +267,15 @@ you can do the following:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('profileData', new Assert\Collection([
-                    'fields' => [
+                $metadata->addPropertyConstraint('profileData', new Assert\Collection(
+                    fields: [
                         'personal_email'  => new Assert\Required([
                             new Assert\NotBlank(),
                             new Assert\Email(),
                         ]),
                         'alternate_email' => new Assert\Optional(new Assert\Email()),
                     ],
-                ]));
+                ));
             }
         }
 
@@ -291,28 +291,28 @@ groups. Take the following example::
 
     use Symfony\Component\Validator\Constraints as Assert;
 
-    $constraint = new Assert\Collection([
-        'fields' => [
+    $constraint = new Assert\Collection(
+        fields: [
             'name' => new Assert\NotBlank(['groups' => 'basic']),
             'email' => new Assert\NotBlank(['groups' => 'contact']),
         ],
-    ]);
+    );
 
 This will result in the following configuration::
 
-    $constraint = new Assert\Collection([
-        'fields' => [
-            'name' => new Assert\Required([
-                'constraints' => new Assert\NotBlank(['groups' => 'basic']),
-                'groups' => ['basic', 'strict'],
-            ]),
-            'email' => new Assert\Required([
-                "constraints" => new Assert\NotBlank(['groups' => 'contact']),
-                'groups' => ['basic', 'strict'],
-            ]),
+    $constraint = new Assert\Collection(
+        fields: [
+            'name' => new Assert\Required(
+                constraints: new Assert\NotBlank(groups: ['basic']),
+                groups: ['basic', 'strict'],
+            ),
+            'email' => new Assert\Required(
+                constraints: new Assert\NotBlank(groups: ['contact']),
+                groups: ['basic', 'strict'],
+            ),
         ],
-        'groups' => ['basic', 'strict'],
-    ]);
+        groups: ['basic', 'strict'],
+    );
 
 The default ``allowMissingFields`` option requires the fields in all groups.
 So when validating in ``contact`` group, ``$name`` can be empty but the key is
@@ -360,7 +360,7 @@ Parameter        Description
 ``fields``
 ~~~~~~~~~~
 
-**type**: ``array`` [:ref:`default option <validation-default-option>`]
+**type**: ``array``
 
 This option is required and is an associative array defining all of the
 keys in the collection and, for each key, exactly which validator(s) should
diff --git a/reference/constraints/Compound.rst b/reference/constraints/Compound.rst
index 0d0dc933ae0..4d2c7743176 100644
--- a/reference/constraints/Compound.rst
+++ b/reference/constraints/Compound.rst
@@ -35,9 +35,9 @@ you can create your own named set or requirements to be reused consistently ever
                 return [
                     new Assert\NotBlank(),
                     new Assert\Type('string'),
-                    new Assert\Length(['min' => 12]),
+                    new Assert\Length(min: 12),
                     new Assert\NotCompromisedPassword(),
-                    new Assert\PasswordStrength(['minScore' => 4]),
+                    new Assert\PasswordStrength(minScore: 4),
                 ];
             }
         }
diff --git a/reference/constraints/Count.rst b/reference/constraints/Count.rst
index 0bf40aca8e9..d33c54c0812 100644
--- a/reference/constraints/Count.rst
+++ b/reference/constraints/Count.rst
@@ -82,12 +82,12 @@ you might add the following:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('emails', new Assert\Count([
-                    'min' => 1,
-                    'max' => 5,
-                    'minMessage' => 'You must specify at least one email',
-                    'maxMessage' => 'You cannot specify more than {{ limit }} emails',
-                ]));
+                $metadata->addPropertyConstraint('emails', new Assert\Count(
+                    min: 1,
+                    max: 5,
+                    minMessage: 'You must specify at least one email',
+                    maxMessage: 'You cannot specify more than {{ limit }} emails',
+                ));
             }
         }
 
diff --git a/reference/constraints/CssColor.rst b/reference/constraints/CssColor.rst
index 88a4eb4be9f..b617ebf1c42 100644
--- a/reference/constraints/CssColor.rst
+++ b/reference/constraints/CssColor.rst
@@ -110,15 +110,15 @@ the named CSS colors:
             {
                 $metadata->addPropertyConstraint('defaultColor', new Assert\CssColor());
 
-                $metadata->addPropertyConstraint('accentColor', new Assert\CssColor([
-                    'formats' => Assert\CssColor::HEX_LONG,
-                    'message' => 'The accent color must be a 6-character hexadecimal color.',
-                ]));
-
-                $metadata->addPropertyConstraint('currentColor', new Assert\CssColor([
-                    'formats' => [Assert\CssColor::BASIC_NAMED_COLORS, Assert\CssColor::EXTENDED_NAMED_COLORS],
-                    'message' => 'The color "{{ value }}" is not a valid CSS color name.',
-                ]));
+                $metadata->addPropertyConstraint('accentColor', new Assert\CssColor(
+                    formats: Assert\CssColor::HEX_LONG,
+                    message: 'The accent color must be a 6-character hexadecimal color.',
+                ));
+
+                $metadata->addPropertyConstraint('currentColor', new Assert\CssColor(
+                    formats: [Assert\CssColor::BASIC_NAMED_COLORS, Assert\CssColor::EXTENDED_NAMED_COLORS],
+                    message: 'The color "{{ value }}" is not a valid CSS color name.',
+                ));
             }
         }
 
diff --git a/reference/constraints/DivisibleBy.rst b/reference/constraints/DivisibleBy.rst
index dd90ad9a0fd..23b36023cff 100644
--- a/reference/constraints/DivisibleBy.rst
+++ b/reference/constraints/DivisibleBy.rst
@@ -92,9 +92,9 @@ The following constraints ensure that:
             {
                 $metadata->addPropertyConstraint('weight', new Assert\DivisibleBy(0.25));
 
-                $metadata->addPropertyConstraint('quantity', new Assert\DivisibleBy([
-                    'value' => 5,
-                ]));
+                $metadata->addPropertyConstraint('quantity', new Assert\DivisibleBy(
+                    value: 5,
+                ));
             }
         }
 
diff --git a/reference/constraints/Email.rst b/reference/constraints/Email.rst
index 516d6d07dca..41012e5e935 100644
--- a/reference/constraints/Email.rst
+++ b/reference/constraints/Email.rst
@@ -70,9 +70,9 @@ Basic Usage
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('email', new Assert\Email([
-                    'message' => 'The email "{{ value }}" is not a valid email.',
-                ]));
+                $metadata->addPropertyConstraint('email', new Assert\Email(
+                    message: 'The email "{{ value }}" is not a valid email.',
+                ));
             }
         }
 
diff --git a/reference/constraints/EqualTo.rst b/reference/constraints/EqualTo.rst
index d5d78f60a0f..fdc402b1a97 100644
--- a/reference/constraints/EqualTo.rst
+++ b/reference/constraints/EqualTo.rst
@@ -91,9 +91,9 @@ and that the ``age`` is ``20``, you could do the following:
             {
                 $metadata->addPropertyConstraint('firstName', new Assert\EqualTo('Mary'));
 
-                $metadata->addPropertyConstraint('age', new Assert\EqualTo([
-                    'value' => 20,
-                ]));
+                $metadata->addPropertyConstraint('age', new Assert\EqualTo(
+                    value: 20,
+                ));
             }
         }
 
diff --git a/reference/constraints/Expression.rst b/reference/constraints/Expression.rst
index bf015d17573..518c5c1f160 100644
--- a/reference/constraints/Expression.rst
+++ b/reference/constraints/Expression.rst
@@ -111,10 +111,10 @@ One way to accomplish this is with the Expression constraint:
         {
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addConstraint(new Assert\Expression([
-                    'expression' => 'this.getCategory() in ["php", "symfony"] or !this.isTechnicalPost()',
-                    'message' => 'If this is a tech post, the category should be either php or symfony!',
-                ]));
+                $metadata->addConstraint(new Assert\Expression(
+                    expression: 'this.getCategory() in ["php", "symfony"] or !this.isTechnicalPost()',
+                    message: 'If this is a tech post, the category should be either php or symfony!',
+                ));
             }
 
             // ...
@@ -200,10 +200,10 @@ assert that the expression must return ``true`` for validation to fail.
             {
                 public static function loadValidatorMetadata(ClassMetadata $metadata): void
                 {
-                    $metadata->addPropertyConstraint('isTechnicalPost', new Assert\Expression([
-                        'expression' => 'this.getCategory() in ["php", "symfony"] or value == false',
-                        'message' => 'If this is a tech post, the category should be either php or symfony!',
-                    ]));
+                    $metadata->addPropertyConstraint('isTechnicalPost', new Assert\Expression(
+                        expression: 'this.getCategory() in ["php", "symfony"] or value == false',
+                        message: 'If this is a tech post, the category should be either php or symfony!',
+                    ));
                 }
 
                 // ...
@@ -227,7 +227,7 @@ Options
 ``expression``
 ~~~~~~~~~~~~~~
 
-**type**: ``string`` [:ref:`default option <validation-default-option>`]
+**type**: ``string``
 
 The expression that will be evaluated. If the expression evaluates to a false
 value (using ``==``, not ``===``), validation will fail. Learn more about the
@@ -343,10 +343,10 @@ type (numeric, boolean, strings, null, etc.)
         {
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('metric', new Assert\Expression([
-                    'expression' => 'value + error_margin < threshold',
-                    'values' => ['error_margin' => 0.25, 'threshold' => 1.5],
-                ]));
+                $metadata->addPropertyConstraint('metric', new Assert\Expression(
+                    expression: 'value + error_margin < threshold',
+                    values: ['error_margin' => 0.25, 'threshold' => 1.5],
+                ));
             }
 
             // ...
diff --git a/reference/constraints/ExpressionSyntax.rst b/reference/constraints/ExpressionSyntax.rst
index c1d086790c1..37e0ad7de4a 100644
--- a/reference/constraints/ExpressionSyntax.rst
+++ b/reference/constraints/ExpressionSyntax.rst
@@ -90,9 +90,9 @@ The following constraints ensure that:
             {
                 $metadata->addPropertyConstraint('promotion', new Assert\ExpressionSyntax());
 
-                $metadata->addPropertyConstraint('shippingOptions', new Assert\ExpressionSyntax([
-                    'allowedVariables' => ['user', 'shipping_centers'],
-                ]));
+                $metadata->addPropertyConstraint('shippingOptions', new Assert\ExpressionSyntax(
+                    allowedVariables: ['user', 'shipping_centers'],
+                ));
             }
         }
 
diff --git a/reference/constraints/File.rst b/reference/constraints/File.rst
index 6d9b72d17b8..495c19f9cbe 100644
--- a/reference/constraints/File.rst
+++ b/reference/constraints/File.rst
@@ -119,13 +119,13 @@ below a certain file size and a valid PDF, add the following:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('bioFile', new Assert\File([
-                    'maxSize' => '1024k',
-                    'extensions' => [
+                $metadata->addPropertyConstraint('bioFile', new Assert\File(
+                    maxSize: '1024k',
+                    extensions: [
                         'pdf',
                     ],
-                    'extensionsMessage' => 'Please upload a valid PDF',
-                ]));
+                    extensionsMessage: 'Please upload a valid PDF',
+                ));
             }
         }
 
diff --git a/reference/constraints/GreaterThan.rst b/reference/constraints/GreaterThan.rst
index 4f2e34bcbfa..d1b79028acd 100644
--- a/reference/constraints/GreaterThan.rst
+++ b/reference/constraints/GreaterThan.rst
@@ -89,9 +89,9 @@ The following constraints ensure that:
             {
                 $metadata->addPropertyConstraint('siblings', new Assert\GreaterThan(5));
 
-                $metadata->addPropertyConstraint('age', new Assert\GreaterThan([
-                    'value' => 18,
-                ]));
+                $metadata->addPropertyConstraint('age', new Assert\GreaterThan(
+                    value: 18,
+                ));
             }
         }
 
diff --git a/reference/constraints/GreaterThanOrEqual.rst b/reference/constraints/GreaterThanOrEqual.rst
index e5a71e5f788..63c2ade6197 100644
--- a/reference/constraints/GreaterThanOrEqual.rst
+++ b/reference/constraints/GreaterThanOrEqual.rst
@@ -88,9 +88,9 @@ The following constraints ensure that:
             {
                 $metadata->addPropertyConstraint('siblings', new Assert\GreaterThanOrEqual(5));
 
-                $metadata->addPropertyConstraint('age', new Assert\GreaterThanOrEqual([
-                    'value' => 18,
-                ]));
+                $metadata->addPropertyConstraint('age', new Assert\GreaterThanOrEqual(
+                    value: 18,
+                ));
             }
         }
 
diff --git a/reference/constraints/Hostname.rst b/reference/constraints/Hostname.rst
index 95b10d1736e..58ac0364669 100644
--- a/reference/constraints/Hostname.rst
+++ b/reference/constraints/Hostname.rst
@@ -72,9 +72,9 @@ will contain a host name.
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('name', new Assert\Hostname([
-                    'message' => 'The server name must be a valid hostname.',
-                ]));
+                $metadata->addPropertyConstraint('name', new Assert\Hostname(
+                    message: 'The server name must be a valid hostname.',
+                ));
             }
         }
 
diff --git a/reference/constraints/Iban.rst b/reference/constraints/Iban.rst
index 3cf800200e2..8d5982eea6d 100644
--- a/reference/constraints/Iban.rst
+++ b/reference/constraints/Iban.rst
@@ -77,9 +77,9 @@ will contain an International Bank Account Number.
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('bankAccountNumber', new Assert\Iban([
-                    'message' => 'This is not a valid International Bank Account Number (IBAN).',
-                ]));
+                $metadata->addPropertyConstraint('bankAccountNumber', new Assert\Iban(
+                    message: 'This is not a valid International Bank Account Number (IBAN).',
+                ));
             }
         }
 
diff --git a/reference/constraints/IdenticalTo.rst b/reference/constraints/IdenticalTo.rst
index 5b6d853dc0b..f8844f90a72 100644
--- a/reference/constraints/IdenticalTo.rst
+++ b/reference/constraints/IdenticalTo.rst
@@ -94,9 +94,9 @@ The following constraints ensure that:
             {
                 $metadata->addPropertyConstraint('firstName', new Assert\IdenticalTo('Mary'));
 
-                $metadata->addPropertyConstraint('age', new Assert\IdenticalTo([
-                    'value' => 20,
-                ]));
+                $metadata->addPropertyConstraint('age', new Assert\IdenticalTo(
+                    value: 20,
+                ));
             }
         }
 
diff --git a/reference/constraints/Image.rst b/reference/constraints/Image.rst
index 23fbe5a157a..5dd270c44f8 100644
--- a/reference/constraints/Image.rst
+++ b/reference/constraints/Image.rst
@@ -116,12 +116,12 @@ that it is between a certain size, add the following:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('headshot', new Assert\Image([
-                    'minWidth' => 200,
-                    'maxWidth' => 400,
-                    'minHeight' => 200,
-                    'maxHeight' => 400,
-                ]));
+                $metadata->addPropertyConstraint('headshot', new Assert\Image(
+                    minWidth: 200,
+                    maxWidth: 400,
+                    minHeight: 200,
+                    maxHeight: 400,
+                ));
             }
         }
 
@@ -187,10 +187,10 @@ following code:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('headshot', new Assert\Image([
-                    'allowLandscape' => false,
-                    'allowPortrait' => false,
-                ]));
+                $metadata->addPropertyConstraint('headshot', new Assert\Image(
+                    allowLandscape: false,
+                    allowPortrait: false,
+                ));
             }
         }
 
diff --git a/reference/constraints/IsFalse.rst b/reference/constraints/IsFalse.rst
index 0b9ebe77491..3d0a1665944 100644
--- a/reference/constraints/IsFalse.rst
+++ b/reference/constraints/IsFalse.rst
@@ -93,9 +93,9 @@ method returns **false**:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addGetterConstraint('stateInvalid', new Assert\IsFalse([
-                    'message' => "You've entered an invalid state.",
-                ]));
+                $metadata->addGetterConstraint('stateInvalid', new Assert\IsFalse(
+                    message: "You've entered an invalid state.",
+                ));
             }
 
             public function isStateInvalid(): bool
diff --git a/reference/constraints/IsTrue.rst b/reference/constraints/IsTrue.rst
index 678371f6e69..b50ba4f3e8b 100644
--- a/reference/constraints/IsTrue.rst
+++ b/reference/constraints/IsTrue.rst
@@ -97,9 +97,9 @@ Then you can validate this method with ``IsTrue`` as follows:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addGetterConstraint('tokenValid', new IsTrue([
-                    'message' => 'The token is invalid.',
-                ]));
+                $metadata->addGetterConstraint('tokenValid', new IsTrue(
+                    message: 'The token is invalid.',
+                ));
             }
 
             public function isTokenValid(): bool
diff --git a/reference/constraints/Isbn.rst b/reference/constraints/Isbn.rst
index 954bff233d5..52d10565fe5 100644
--- a/reference/constraints/Isbn.rst
+++ b/reference/constraints/Isbn.rst
@@ -76,10 +76,10 @@ on an object that will contain an ISBN.
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('isbn', new Assert\Isbn([
-                    'type' => Assert\Isbn::ISBN_10,
-                    'message' => 'This value is not valid.',
-                ]));
+                $metadata->addPropertyConstraint('isbn', new Assert\Isbn(
+                    type: Assert\Isbn::ISBN_10,
+                    message: 'This value is not valid.',
+                ));
             }
         }
 
diff --git a/reference/constraints/Json.rst b/reference/constraints/Json.rst
index 28e15976f3c..337b2dc6a1e 100644
--- a/reference/constraints/Json.rst
+++ b/reference/constraints/Json.rst
@@ -69,9 +69,9 @@ The ``Json`` constraint can be applied to a property or a "getter" method:
         {
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('chapters', new Assert\Json([
-                    'message' => 'You\'ve entered an invalid Json.',
-                ]));
+                $metadata->addPropertyConstraint('chapters', new Assert\Json(
+                    message: 'You\'ve entered an invalid Json.',
+                ));
             }
         }
 
diff --git a/reference/constraints/Length.rst b/reference/constraints/Length.rst
index 9a4478f509b..c1a8575070b 100644
--- a/reference/constraints/Length.rst
+++ b/reference/constraints/Length.rst
@@ -85,12 +85,12 @@ and ``50``, you might add the following:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('firstName', new Assert\Length([
-                    'min' => 2,
-                    'max' => 50,
-                    'minMessage' => 'Your first name must be at least {{ limit }} characters long',
-                    'maxMessage' => 'Your first name cannot be longer than {{ limit }} characters',
-                ]));
+                $metadata->addPropertyConstraint('firstName', new Assert\Length(
+                    min: 2,
+                    max: 50,
+                    minMessage: 'Your first name must be at least {{ limit }} characters long',
+                    maxMessage: 'Your first name cannot be longer than {{ limit }} characters',
+                ));
             }
         }
 
diff --git a/reference/constraints/LessThan.rst b/reference/constraints/LessThan.rst
index 964bfbb3527..3d23bcda445 100644
--- a/reference/constraints/LessThan.rst
+++ b/reference/constraints/LessThan.rst
@@ -89,9 +89,9 @@ The following constraints ensure that:
             {
                 $metadata->addPropertyConstraint('siblings', new Assert\LessThan(5));
 
-                $metadata->addPropertyConstraint('age', new Assert\LessThan([
-                    'value' => 80,
-                ]));
+                $metadata->addPropertyConstraint('age', new Assert\LessThan(
+                    value: 80,
+                ));
             }
         }
 
diff --git a/reference/constraints/LessThanOrEqual.rst b/reference/constraints/LessThanOrEqual.rst
index 9420c3e4376..ac66c62d7d0 100644
--- a/reference/constraints/LessThanOrEqual.rst
+++ b/reference/constraints/LessThanOrEqual.rst
@@ -88,9 +88,9 @@ The following constraints ensure that:
             {
                 $metadata->addPropertyConstraint('siblings', new Assert\LessThanOrEqual(5));
 
-                $metadata->addPropertyConstraint('age', new Assert\LessThanOrEqual([
-                    'value' => 80,
-                ]));
+                $metadata->addPropertyConstraint('age', new Assert\LessThanOrEqual(
+                    value: 80,
+                ));
             }
         }
 
diff --git a/reference/constraints/Locale.rst b/reference/constraints/Locale.rst
index 49edd473d05..4bba45ae12b 100644
--- a/reference/constraints/Locale.rst
+++ b/reference/constraints/Locale.rst
@@ -78,9 +78,9 @@ Basic Usage
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('locale', new Assert\Locale([
-                    'canonicalize' => true,
-                ]));
+                $metadata->addPropertyConstraint('locale', new Assert\Locale(
+                    canonicalize: true,
+                ));
             }
         }
 
diff --git a/reference/constraints/Luhn.rst b/reference/constraints/Luhn.rst
index 8f5ef34c4ba..0c835204091 100644
--- a/reference/constraints/Luhn.rst
+++ b/reference/constraints/Luhn.rst
@@ -72,9 +72,9 @@ will contain a credit card number.
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('cardNumber', new Assert\Luhn([
-                    'message' => 'Please check your credit card number',
-                ]));
+                $metadata->addPropertyConstraint('cardNumber', new Assert\Luhn(
+                    message: 'Please check your credit card number',
+                ));
             }
         }
 
diff --git a/reference/constraints/NotEqualTo.rst b/reference/constraints/NotEqualTo.rst
index b8ee4cac32f..dd3f633b4a1 100644
--- a/reference/constraints/NotEqualTo.rst
+++ b/reference/constraints/NotEqualTo.rst
@@ -93,9 +93,9 @@ the following:
             {
                 $metadata->addPropertyConstraint('firstName', new Assert\NotEqualTo('Mary'));
 
-                $metadata->addPropertyConstraint('age', new Assert\NotEqualTo([
-                    'value' => 15,
-                ]));
+                $metadata->addPropertyConstraint('age', new Assert\NotEqualTo(
+                    value: 15,
+                ));
             }
         }
 
diff --git a/reference/constraints/NotIdenticalTo.rst b/reference/constraints/NotIdenticalTo.rst
index 9ea93dc4b86..b2c20027292 100644
--- a/reference/constraints/NotIdenticalTo.rst
+++ b/reference/constraints/NotIdenticalTo.rst
@@ -94,9 +94,9 @@ The following constraints ensure that:
             {
                 $metadata->addPropertyConstraint('age', new Assert\NotIdenticalTo('Mary'));
 
-                $metadata->addPropertyConstraint('age', new Assert\NotIdenticalTo([
-                    'value' => 15,
-                ]));
+                $metadata->addPropertyConstraint('age', new Assert\NotIdenticalTo(
+                    value: 15,
+                ));
             }
         }
 
diff --git a/reference/constraints/PasswordStrength.rst b/reference/constraints/PasswordStrength.rst
index 60125a763a1..0b242cacf08 100644
--- a/reference/constraints/PasswordStrength.rst
+++ b/reference/constraints/PasswordStrength.rst
@@ -101,9 +101,9 @@ or by a custom password strength estimator.
 
     class User
     {
-        #[Assert\PasswordStrength([
-            'minScore' => PasswordStrength::STRENGTH_VERY_STRONG, // Very strong password required
-        ])]
+        #[Assert\PasswordStrength(
+            minScore: PasswordStrength::STRENGTH_VERY_STRONG, // Very strong password required
+        )]
         protected $rawPassword;
     }
 
@@ -123,9 +123,9 @@ The default message supplied when the password does not reach the minimum requir
 
     class User
     {
-        #[Assert\PasswordStrength([
-            'message' => 'Your password is too easy to guess. Company\'s security policy requires to use a stronger password.'
-        ])]
+        #[Assert\PasswordStrength(
+            message: 'Your password is too easy to guess. Company\'s security policy requires to use a stronger password.'
+        )]
         protected $rawPassword;
     }
 
diff --git a/reference/constraints/Range.rst b/reference/constraints/Range.rst
index edd199c48b9..46a9e3799b3 100644
--- a/reference/constraints/Range.rst
+++ b/reference/constraints/Range.rst
@@ -78,11 +78,11 @@ you might add the following:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('height', new Assert\Range([
-                    'min' => 120,
-                    'max' => 180,
-                    'notInRangeMessage' => 'You must be between {{ min }}cm and {{ max }}cm tall to enter',
-                ]));
+                $metadata->addPropertyConstraint('height', new Assert\Range(
+                    min: 120,
+                    max: 180,
+                    notInRangeMessage: 'You must be between {{ min }}cm and {{ max }}cm tall to enter',
+                ));
             }
         }
 
@@ -154,10 +154,10 @@ date must lie within the current year like this:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('startDate', new Assert\Range([
-                    'min' => 'first day of January',
-                    'max' => 'first day of January next year',
-                ]));
+                $metadata->addPropertyConstraint('startDate', new Assert\Range(
+                    min: 'first day of January',
+                    max: 'first day of January next year',
+                ));
             }
         }
 
@@ -224,10 +224,10 @@ dates. If you want to fix the timezone, append it to the date string:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('startDate', new Assert\Range([
-                    'min' => 'first day of January UTC',
-                    'max' => 'first day of January next year UTC',
-                ]));
+                $metadata->addPropertyConstraint('startDate', new Assert\Range(
+                    min: 'first day of January UTC',
+                    max: 'first day of January next year UTC',
+                ));
             }
         }
 
@@ -294,10 +294,10 @@ can check that a delivery date starts within the next five hours like this:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('deliveryDate', new Assert\Range([
-                    'min' => 'now',
-                    'max' => '+5 hours',
-                ]));
+                $metadata->addPropertyConstraint('deliveryDate', new Assert\Range(
+                    min: 'now',
+                    max: '+5 hours',
+                ));
             }
         }
 
diff --git a/reference/constraints/Regex.rst b/reference/constraints/Regex.rst
index 2e11a8d04fc..e3b4d4711b2 100644
--- a/reference/constraints/Regex.rst
+++ b/reference/constraints/Regex.rst
@@ -71,9 +71,9 @@ more word characters at the beginning of your string:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('description', new Assert\Regex([
-                    'pattern' => '/^\w+/',
-                ]));
+                $metadata->addPropertyConstraint('description', new Assert\Regex(
+                    pattern: '/^\w+/',
+                ));
             }
         }
 
@@ -145,11 +145,11 @@ it a custom message:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('firstName', new Assert\Regex([
-                    'pattern' => '/\d/',
-                    'match' => false,
-                    'message' => 'Your name cannot contain a number',
-                ]));
+                $metadata->addPropertyConstraint('firstName', new Assert\Regex(
+                    pattern: '/\d/',
+                    match: false,
+                    message: 'Your name cannot contain a number',
+                ));
             }
         }
 
@@ -236,10 +236,10 @@ need to specify the HTML5 compatible pattern in the ``htmlPattern`` option:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('name', new Assert\Regex([
-                    'pattern' => '/^[a-z]+$/i',
-                    'htmlPattern' => '[a-zA-Z]+',
-                ]));
+                $metadata->addPropertyConstraint('name', new Assert\Regex(
+                    pattern: '/^[a-z]+$/i',
+                    htmlPattern: '[a-zA-Z]+',
+                ));
             }
         }
 
@@ -275,7 +275,7 @@ Parameter          Description
 ``pattern``
 ~~~~~~~~~~~
 
-**type**: ``string`` [:ref:`default option <validation-default-option>`]
+**type**: ``string``
 
 This required option is the regular expression pattern that the input will
 be matched against. By default, this validator will fail if the input string
diff --git a/reference/constraints/Sequentially.rst b/reference/constraints/Sequentially.rst
index 7620997f0a3..078be338cdf 100644
--- a/reference/constraints/Sequentially.rst
+++ b/reference/constraints/Sequentially.rst
@@ -110,7 +110,7 @@ You can validate each of these constraints sequentially to solve these issues:
                 $metadata->addPropertyConstraint('address', new Assert\Sequentially([
                     new Assert\NotNull(),
                     new Assert\Type('string'),
-                    new Assert\Length(['min' => 10]),
+                    new Assert\Length(min: 10),
                     new Assert\Regex(self::ADDRESS_REGEX),
                     new AcmeAssert\Geolocalizable(),
                 ]));
@@ -123,7 +123,7 @@ Options
 ``constraints``
 ~~~~~~~~~~~~~~~
 
-**type**: ``array`` [:ref:`default option <validation-default-option>`]
+**type**: ``array``
 
 This required option is the array of validation constraints that you want
 to apply sequentially.
diff --git a/reference/constraints/Type.rst b/reference/constraints/Type.rst
index b99e8ce1c54..b49536dff8b 100644
--- a/reference/constraints/Type.rst
+++ b/reference/constraints/Type.rst
@@ -127,14 +127,14 @@ The following example checks if ``emailAddress`` is an instance of ``Symfony\Com
 
                 $metadata->addPropertyConstraint('firstName', new Assert\Type('string'));
 
-                $metadata->addPropertyConstraint('age', new Assert\Type([
-                    'type' => 'integer',
-                    'message' => 'The value {{ value }} is not a valid {{ type }}.',
-                ]));
-
-                $metadata->addPropertyConstraint('accessCode', new Assert\Type([
-                    'type' => ['alpha', 'digit'],
-                ]));
+                $metadata->addPropertyConstraint('age', new Assert\Type(
+                    type: 'integer',
+                    message: 'The value {{ value }} is not a valid {{ type }}.',
+                ));
+
+                $metadata->addPropertyConstraint('accessCode', new Assert\Type(
+                    type: ['alpha', 'digit'],
+                ));
             }
         }
 
@@ -169,7 +169,7 @@ Parameter        Description
 ``type``
 ~~~~~~~~
 
-**type**: ``string`` or ``array`` [:ref:`default option <validation-default-option>`]
+**type**: ``string`` or ``array``
 
 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
diff --git a/reference/constraints/Unique.rst b/reference/constraints/Unique.rst
index 68754738271..a1be67d6f2f 100644
--- a/reference/constraints/Unique.rst
+++ b/reference/constraints/Unique.rst
@@ -162,9 +162,9 @@ collection::
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('coordinates', new Assert\Unique([
-                    'fields' => ['latitude', 'longitude'],
-                ]));
+                $metadata->addPropertyConstraint('coordinates', new Assert\Unique(
+                    fields: ['latitude', 'longitude'],
+                ));
             }
         }
 
diff --git a/reference/constraints/UniqueEntity.rst b/reference/constraints/UniqueEntity.rst
index d4fbfeb8666..e819a8009dc 100644
--- a/reference/constraints/UniqueEntity.rst
+++ b/reference/constraints/UniqueEntity.rst
@@ -95,9 +95,9 @@ between all of the rows in your user table:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addConstraint(new UniqueEntity([
-                    'fields' => 'email',
-                ]));
+                $metadata->addConstraint(new UniqueEntity(
+                    fields: 'email',
+                ));
 
                 $metadata->addPropertyConstraint('email', new Assert\Email());
             }
@@ -260,7 +260,7 @@ Now, the message would be bound to the ``port`` field with this configuration.
 ``fields``
 ~~~~~~~~~~
 
-**type**: ``array`` | ``string`` [:ref:`default option <validation-default-option>`]
+**type**: ``array`` | ``string``
 
 This required option is the field (or list of fields) on which this entity
 should be unique. For example, if you specified both the ``email`` and ``name``
@@ -346,10 +346,10 @@ this option to specify one or more fields to only ignore ``null`` values on them
         {
             public static function loadValidatorMetadata(ClassMetadata $metadata)
             {
-                $metadata->addConstraint(new UniqueEntity([
-                    'fields' => ['email', 'phoneNumber'],
-                    'ignoreNull' => 'phoneNumber',
-                ]));
+                $metadata->addConstraint(new UniqueEntity(
+                    fields: ['email', 'phoneNumber'],
+                    ignoreNull: 'phoneNumber',
+                ));
 
                 // ...
             }
diff --git a/reference/constraints/Url.rst b/reference/constraints/Url.rst
index 74f0d750dfd..fbeaa6da522 100644
--- a/reference/constraints/Url.rst
+++ b/reference/constraints/Url.rst
@@ -152,9 +152,9 @@ Parameter        Description
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('bioUrl', new Assert\Url([
-                    'message' => 'The url "{{ value }}" is not a valid url.',
-                ]));
+                $metadata->addPropertyConstraint('bioUrl', new Assert\Url(
+                    message: 'The url "{{ value }}" is not a valid url.',
+                ));
             }
         }
 
@@ -231,9 +231,9 @@ the ``ftp://`` type URLs to be valid, redefine the ``protocols`` array, listing
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('bioUrl', new Assert\Url([
-                    'protocols' => ['http', 'https', 'ftp'],
-                ]));
+                $metadata->addPropertyConstraint('bioUrl', new Assert\Url(
+                    protocols: ['http', 'https', 'ftp'],
+                ));
             }
         }
 
@@ -302,9 +302,9 @@ also relative URLs that contain no protocol (e.g. ``//example.com``).
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('bioUrl', new Assert\Url([
-                    'relativeProtocol' => true,
-                ]));
+                $metadata->addPropertyConstraint('bioUrl', new Assert\Url(
+                    relativeProtocol: true,
+                ));
             }
         }
 
@@ -414,10 +414,10 @@ Parameter        Description
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('homepageUrl', new Assert\Url([
-                    'requireTld' => true,
-                    'tldMessage' => 'Add at least one TLD to the {{ value }} URL.',
-                ]));
+                $metadata->addPropertyConstraint('homepageUrl', new Assert\Url(
+                    requireTld: true,
+                    tldMessage: 'Add at least one TLD to the {{ value }} URL.',
+                ));
             }
         }
 
diff --git a/reference/constraints/Valid.rst b/reference/constraints/Valid.rst
index 1f99b666419..61a2c1d992c 100644
--- a/reference/constraints/Valid.rst
+++ b/reference/constraints/Valid.rst
@@ -149,7 +149,7 @@ stores an ``Address`` instance in the ``$address`` property::
             {
                 $metadata->addPropertyConstraint('street', new Assert\NotBlank());
                 $metadata->addPropertyConstraint('zipCode', new Assert\NotBlank());
-                $metadata->addPropertyConstraint('zipCode', new Assert\Length(['max' => 5]));
+                $metadata->addPropertyConstraint('zipCode', new Assert\Length(max: 5));
             }
         }
 
@@ -166,7 +166,7 @@ stores an ``Address`` instance in the ``$address`` property::
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
                 $metadata->addPropertyConstraint('firstName', new Assert\NotBlank());
-                $metadata->addPropertyConstraint('firstName', new Assert\Length(['min' => 4]));
+                $metadata->addPropertyConstraint('firstName', new Assert\Length(min: 4));
                 $metadata->addPropertyConstraint('lastName', new Assert\NotBlank());
             }
         }
diff --git a/reference/constraints/Week.rst b/reference/constraints/Week.rst
index f107d8b4192..b3c1b0ca122 100644
--- a/reference/constraints/Week.rst
+++ b/reference/constraints/Week.rst
@@ -79,10 +79,10 @@ the following:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('startWeek', new Assert\Week([
-                    'min' => '2022-W01',
-                    'max' => '2022-W20',
-                ]));
+                $metadata->addPropertyConstraint('startWeek', new Assert\Week(
+                    min: '2022-W01',
+                    max: '2022-W20',
+                ));
             }
         }
 
diff --git a/reference/constraints/When.rst b/reference/constraints/When.rst
index 2a05e58ee9c..ec21eca9784 100644
--- a/reference/constraints/When.rst
+++ b/reference/constraints/When.rst
@@ -127,15 +127,15 @@ One way to accomplish this is with the When constraint:
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
                 $metadata->addPropertyConstraint('value', new Assert\GreaterThan(0));
-                $metadata->addPropertyConstraint('value', new Assert\When([
-                    'expression' => 'this.getType() == "percent"',
-                    'constraints' => [
-                        new Assert\LessThanOrEqual([
-                            'value' => 100,
-                            'message' => 'The value should be between 1 and 100!',
-                        ]),
+                $metadata->addPropertyConstraint('value', new Assert\When(
+                    expression: 'this.getType() == "percent"',
+                    constraints: [
+                        new Assert\LessThanOrEqual(
+                            value: 100,
+                            message: 'The value should be between 1 and 100!',
+                        ),
                     ],
-                ]));
+                ));
             }
 
             // ...
@@ -256,12 +256,12 @@ validation based on its value:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('type', new Assert\When([
-                    'expression' => 'value == "percent"',
-                    'constraints' => [
+                $metadata->addPropertyConstraint('type', new Assert\When(
+                    expression: 'value == "percent"',
+                    constraints: [
                         new Assert\Callback('doComplexValidation'),
                     ],
-                ]));
+                ));
             }
 
             public function doComplexValidation(ExecutionContextInterface $context, $payload): void
diff --git a/reference/constraints/WordCount.rst b/reference/constraints/WordCount.rst
index 74c79216898..392f8a5bcb7 100644
--- a/reference/constraints/WordCount.rst
+++ b/reference/constraints/WordCount.rst
@@ -78,10 +78,10 @@ class contains between 100 and 200 words, you could do the following:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('content', new Assert\WordCount([
-                    'min' => 100,
-                    'max' => 200,
-                ]));
+                $metadata->addPropertyConstraint('content', new Assert\WordCount(
+                    min: 100,
+                    max: 200,
+                ));
             }
         }
 
diff --git a/reference/constraints/Yaml.rst b/reference/constraints/Yaml.rst
index 49b65f251e8..0d1564f4f8a 100644
--- a/reference/constraints/Yaml.rst
+++ b/reference/constraints/Yaml.rst
@@ -73,9 +73,9 @@ The ``Yaml`` constraint can be applied to a property or a "getter" method:
         {
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('customConfiguration', new Assert\Yaml([
-                    'message' => 'Your configuration doesn\'t have valid YAML syntax.',
-                ]));
+                $metadata->addPropertyConstraint('customConfiguration', new Assert\Yaml(
+                    message: 'Your configuration doesn\'t have valid YAML syntax.',
+                ));
             }
         }
 
@@ -122,10 +122,10 @@ Its value is a combination of one or more of the :ref:`flags defined by the Yaml
         {
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('customConfiguration', new Assert\Yaml([
-                    'message' => 'Your configuration doesn\'t have valid YAML syntax.',
-                    'flags' => Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS | Yaml::PARSE_DATETIME,
-                ]));
+                $metadata->addPropertyConstraint('customConfiguration', new Assert\Yaml(
+                    message: 'Your configuration doesn\'t have valid YAML syntax.',
+                    flags: Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS | Yaml::PARSE_DATETIME,
+                ));
             }
         }
 
diff --git a/reference/constraints/_comparison-value-option.rst.inc b/reference/constraints/_comparison-value-option.rst.inc
index c8abdfb5af0..91ab28a2e94 100644
--- a/reference/constraints/_comparison-value-option.rst.inc
+++ b/reference/constraints/_comparison-value-option.rst.inc
@@ -1,7 +1,7 @@
 ``value``
 ~~~~~~~~~
 
-**type**: ``mixed`` [:ref:`default option <validation-default-option>`]
+**type**: ``mixed``
 
 This option is required. It defines the comparison value. It can be a
 string, number or object.
diff --git a/validation.rst b/validation.rst
index 4905283b18b..cfa8154b627 100644
--- a/validation.rst
+++ b/validation.rst
@@ -327,99 +327,13 @@ literature genre mostly associated with the author, which can be set to either
             {
                 // ...
 
-                $metadata->addPropertyConstraint('genre', new Assert\Choice([
-                    'choices' => ['fiction', 'non-fiction'],
-                    'message' => 'Choose a valid genre.',
-                ]));
+                $metadata->addPropertyConstraint('genre', new Assert\Choice(
+                    choices: ['fiction', 'non-fiction'],
+                    message: 'Choose a valid genre.',
+                ));
             }
         }
 
-.. _validation-default-option:
-
-The options of a constraint can always be passed in as an array. Some constraints,
-however, also allow you to pass the value of one, "*default*", option in place
-of the array. In the case of the ``Choice`` constraint, the ``choices``
-options can be specified in this way.
-
-.. configuration-block::
-
-    .. code-block:: php-attributes
-
-        // src/Entity/Author.php
-        namespace App\Entity;
-
-        // ...
-        use Symfony\Component\Validator\Constraints as Assert;
-
-        class Author
-        {
-            #[Assert\Choice(['fiction', 'non-fiction'])]
-            private string $genre;
-
-            // ...
-        }
-
-    .. code-block:: yaml
-
-        # config/validator/validation.yaml
-        App\Entity\Author:
-            properties:
-                genre:
-                    - Choice: [fiction, non-fiction]
-                # ...
-
-    .. code-block:: xml
-
-        <!-- config/validator/validation.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
-                https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
-
-            <class name="App\Entity\Author">
-                <property name="genre">
-                    <constraint name="Choice">
-                        <value>fiction</value>
-                        <value>non-fiction</value>
-                    </constraint>
-                </property>
-
-                <!-- ... -->
-            </class>
-        </constraint-mapping>
-
-    .. code-block:: php
-
-        // src/Entity/Author.php
-        namespace App\Entity;
-
-        // ...
-        use Symfony\Component\Validator\Constraints as Assert;
-        use Symfony\Component\Validator\Mapping\ClassMetadata;
-
-        class Author
-        {
-            private string $genre;
-
-            public static function loadValidatorMetadata(ClassMetadata $metadata): void
-            {
-                // ...
-
-                $metadata->addPropertyConstraint(
-                    'genre',
-                    new Assert\Choice(['fiction', 'non-fiction'])
-                );
-            }
-        }
-
-This is purely meant to make the configuration of the most common option of
-a constraint shorter and quicker.
-
-If you're ever unsure of how to specify an option, either check the namespace
-``Symfony\Component\Validator\Constraints`` for the constraint or play it safe
-by always passing in an array of options (the first method shown above).
-
 Constraints in Form Classes
 ---------------------------
 
@@ -520,7 +434,7 @@ class to have at least 3 characters.
                 $metadata->addPropertyConstraint('firstName', new Assert\NotBlank());
                 $metadata->addPropertyConstraint(
                     'firstName',
-                    new Assert\Length(['min' => 3])
+                    new Assert\Length(min: 3)
                 );
             }
         }
@@ -603,9 +517,9 @@ this method must return ``true``:
         {
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addGetterConstraint('passwordSafe', new Assert\IsTrue([
-                    'message' => 'The password cannot match your first name',
-                ]));
+                $metadata->addGetterConstraint('passwordSafe', new Assert\IsTrue(
+                    message: 'The password cannot match your first name',
+                ));
             }
         }
 
diff --git a/validation/custom_constraint.rst b/validation/custom_constraint.rst
index 08ed86fb4ce..bb34775a71c 100644
--- a/validation/custom_constraint.rst
+++ b/validation/custom_constraint.rst
@@ -248,7 +248,7 @@ You can use custom validators like the ones provided by Symfony itself:
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
                 $metadata->addPropertyConstraint('name', new NotBlank());
-                $metadata->addPropertyConstraint('name', new ContainsAlphanumeric(['mode' => 'loose']));
+                $metadata->addPropertyConstraint('name', new ContainsAlphanumeric(mode: 'loose'));
             }
         }
 
@@ -273,6 +273,7 @@ define those options as public properties on the constraint class::
     // src/Validator/Foo.php
     namespace App\Validator;
 
+    use Symfony\Component\Validator\Attribute\HasNamedArguments;
     use Symfony\Component\Validator\Constraint;
 
     #[\Attribute]
@@ -282,6 +283,7 @@ define those options as public properties on the constraint class::
         public $message = 'This value is invalid';
         public $optionalBarOption = false;
 
+        #[HasNamedArguments]
         public function __construct(
             $mandatoryFooOption,
             ?string $message = null,
@@ -402,10 +404,10 @@ the custom options like you pass any other option in built-in constraints:
             public static function loadValidatorMetadata(ClassMetadata $metadata)
             {
                 $metadata->addPropertyConstraint('name', new NotBlank());
-                $metadata->addPropertyConstraint('name', new Foo([
-                    'mandatoryFooOption' => 'bar',
-                    'optionalBarOption' => true,
-                ]));
+                $metadata->addPropertyConstraint('name', new Foo(
+                    mandatoryFooOption: 'bar',
+                    optionalBarOption: true,
+                ));
             }
         }
 
diff --git a/validation/groups.rst b/validation/groups.rst
index 8d84e52c0da..55625be702d 100644
--- a/validation/groups.rst
+++ b/validation/groups.rst
@@ -101,21 +101,21 @@ user registers and when a user updates their contact information later:
         {
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('email', new Assert\Email([
-                    'groups' => ['registration'],
-                ]));
-
-                $metadata->addPropertyConstraint('password', new Assert\NotBlank([
-                    'groups' => ['registration'],
-                ]));
-                $metadata->addPropertyConstraint('password', new Assert\Length([
-                    'min'    => 7,
-                    'groups' => ['registration'],
-                ]));
-
-                $metadata->addPropertyConstraint('city', new Assert\Length([
-                    'min' => 2,
-                ]));
+                $metadata->addPropertyConstraint('email', new Assert\Email(
+                    groups: ['registration'],
+                ));
+
+                $metadata->addPropertyConstraint('password', new Assert\NotBlank(
+                    groups: ['registration'],
+                ));
+                $metadata->addPropertyConstraint('password', new Assert\Length(
+                    min: 7,
+                    groups: ['registration'],
+                ));
+
+                $metadata->addPropertyConstraint('city', new Assert\Length(
+                    min: 2,
+                ));
             }
         }
 
diff --git a/validation/sequence_provider.rst b/validation/sequence_provider.rst
index 836568c2327..c316a85d249 100644
--- a/validation/sequence_provider.rst
+++ b/validation/sequence_provider.rst
@@ -104,10 +104,10 @@ username and the password are different only if all other validation passes
                 $metadata->addPropertyConstraint('username', new Assert\NotBlank());
                 $metadata->addPropertyConstraint('password', new Assert\NotBlank());
 
-                $metadata->addGetterConstraint('passwordSafe', new Assert\IsTrue([
-                    'message' => 'The password cannot match your first name',
-                    'groups'  => ['Strict'],
-                ]));
+                $metadata->addGetterConstraint('passwordSafe', new Assert\IsTrue(
+                    message: 'The password cannot match your first name',
+                    groups: ['Strict'],
+                ));
 
                 $metadata->setGroupSequence(['User', 'Strict']);
             }
@@ -249,10 +249,10 @@ entity and a new constraint group called ``Premium``:
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
                 $metadata->addPropertyConstraint('name', new Assert\NotBlank());
-                $metadata->addPropertyConstraint('creditCard', new Assert\CardScheme([
-                    'schemes' => [Assert\CardScheme::VISA],
-                    'groups'  => ['Premium'],
-                ]));
+                $metadata->addPropertyConstraint('creditCard', new Assert\CardScheme(
+                    schemes: [Assert\CardScheme::VISA],
+                    groups: ['Premium'],
+                ));
             }
         }
 
diff --git a/validation/severity.rst b/validation/severity.rst
index 632a99519d9..154c13d5e3e 100644
--- a/validation/severity.rst
+++ b/validation/severity.rst
@@ -105,15 +105,15 @@ Use the ``payload`` option to configure the error level for each constraint:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('username', new Assert\NotBlank([
-                    'payload' => ['severity' => 'error'],
-                ]));
-                $metadata->addPropertyConstraint('password', new Assert\NotBlank([
-                    'payload' => ['severity' => 'error'],
-                ]));
-                $metadata->addPropertyConstraint('bankAccountNumber', new Assert\Iban([
-                    'payload' => ['severity' => 'warning'],
-                ]));
+                $metadata->addPropertyConstraint('username', new Assert\NotBlank(
+                    payload: ['severity' => 'error'],
+                ));
+                $metadata->addPropertyConstraint('password', new Assert\NotBlank(
+                    payload: ['severity' => 'error'],
+                ));
+                $metadata->addPropertyConstraint('bankAccountNumber', new Assert\Iban(
+                    payload: ['severity' => 'warning'],
+                ));
             }
         }
 
diff --git a/validation/translations.rst b/validation/translations.rst
index 9a4ece17736..db2cd518eb7 100644
--- a/validation/translations.rst
+++ b/validation/translations.rst
@@ -83,9 +83,9 @@ property is not empty, add the following:
 
             public static function loadValidatorMetadata(ClassMetadata $metadata): void
             {
-                $metadata->addPropertyConstraint('name', new NotBlank([
-                    'message' => 'author.name.not_blank',
-                ]));
+                $metadata->addPropertyConstraint('name', new NotBlank(
+                    message: 'author.name.not_blank',
+                ));
             }
         }
 
@@ -136,13 +136,13 @@ You can also use :class:`Symfony\\Component\\Translation\\TranslatableMessage` t
     use Symfony\Component\Translation\TranslatableMessage;
     use Symfony\Component\Validator\Constraints as Assert;
     use Symfony\Component\Validator\Context\ExecutionContextInterface;
-    
+
     #[Assert\Callback]
     public function validate(ExecutionContextInterface $context, mixed $payload): void
     {
         // somehow you have an array of "fake names"
         $fakeNames = [/* ... */];
-    
+
         // check if the name is actually a fake name
         if (in_array($this->getFirstName(), $fakeNames, true)) {
             $context->buildViolation(new TranslatableMessage('author.name.fake', [], 'validators'))

From c8f21886f4a3e60a80ef8cc95a47737d91d1afba Mon Sep 17 00:00:00 2001
From: Michel Roca <mroca.dh@gmail.com>
Date: Mon, 27 Jan 2025 13:27:48 +0100
Subject: [PATCH 498/747] [Notifier] Add SentMessage extra info

---
 notifier.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/notifier.rst b/notifier.rst
index 090f4db2007..4c790125f3e 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -68,6 +68,7 @@ Service
 `AllMySms`_         **Install**: ``composer require symfony/all-my-sms-notifier`` \
                     **DSN**: ``allmysms://LOGIN:APIKEY@default?from=FROM`` \
                     **Webhook support**: No
+                    **SentMessage extra info**: `nbSms`, `balance`, `cost`
 `AmazonSns`_        **Install**: ``composer require symfony/amazon-sns-notifier`` \
                     **DSN**: ``sns://ACCESS_KEY:SECRET_KEY@default?region=REGION`` \
                     **Webhook support**: No
@@ -139,6 +140,7 @@ Service
 `OvhCloud`_         **Install**: ``composer require symfony/ovh-cloud-notifier`` \
                     **DSN**: ``ovhcloud://APPLICATION_KEY:APPLICATION_SECRET@default?consumer_key=CONSUMER_KEY&service_name=SERVICE_NAME`` \
                     **Webhook support**: No
+                    **SentMessage extra info**: `totalCreditsRemoved`
 `Plivo`_            **Install**: ``composer require symfony/plivo-notifier`` \
                     **DSN**: ``plivo://AUTH_ID:AUTH_TOKEN@default?from=FROM`` \
                     **Webhook support**: No

From 8ce8f9ba8491d4afd91f8fa0da0cd1196fe826c6 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Mon, 27 Jan 2025 08:16:36 +0100
Subject: [PATCH 499/747] [Messenger] Describe `--keepalive` option (AmazonSQS
 & Beanstalkd)

---
 messenger.rst | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index 0965cbc9170..217061d302c 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -543,6 +543,19 @@ command with the ``--all`` option:
 
     The ``--all`` option was introduced in Symfony 7.1.
 
+The ``--keepalive`` option can be used to prevent messages from being prematurely
+redelivered during long-running processing. It marks the message as "in progress"
+and prevents it from being redelivered until the worker finishes processing it.
+
+.. note::
+
+    This option is only available for supported transports, which are
+    the Beanstalkd and AmazonSQS transports.
+
+.. versionadded:: 7.2
+
+    The ``--keepalive`` option was introduced in Symfony 7.2.
+
 .. tip::
 
     In a development environment and if you're using the Symfony CLI tool,
@@ -1709,6 +1722,10 @@ The transport has a number of options:
     The message time to run before it is put back in the ready queue - in
     seconds.
 
+.. versionadded:: 7.2
+
+    Keepalive support, using the ``--keepalive`` option, was added in Symfony 7.2.
+
 .. _messenger-redis-transport:
 
 Redis Transport
@@ -2031,6 +2048,10 @@ The transport has a number of options:
     FIFO queues don't support setting a delay per message, a value of ``delay: 0``
     is required in the retry strategy settings.
 
+.. versionadded:: 7.2
+
+    Keepalive support, using the `--keepalive` option, was added in Symfony 7.2.
+
 Serializing Messages
 ~~~~~~~~~~~~~~~~~~~~
 

From 40cafd498e9a0d78e17d7b89735b964203ed0c10 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Tue, 28 Jan 2025 11:05:30 +0100
Subject: [PATCH 500/747] [Messenger] Update docs for keepalive support in
 doctrine messenger transport

closes #20599
---
 messenger.rst | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index 217061d302c..727b1fbc39a 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -545,12 +545,16 @@ command with the ``--all`` option:
 
 The ``--keepalive`` option can be used to prevent messages from being prematurely
 redelivered during long-running processing. It marks the message as "in progress"
-and prevents it from being redelivered until the worker finishes processing it.
+and prevents it from being redelivered until the worker finishes processing it:
+
+.. code-block:: terminal
+
+    php bin/console messenger:consume --keepalive=5
 
 .. note::
 
     This option is only available for supported transports, which are
-    the Beanstalkd and AmazonSQS transports.
+    the Doctrine, Beanstalkd and AmazonSQS transports.
 
 .. versionadded:: 7.2
 
@@ -1689,6 +1693,14 @@ in the table.
     The length of time to wait for a response when calling
     ``PDO::pgsqlGetNotify``, in milliseconds.
 
+The keepalive feature, which prevents messages from being prematurely redelivered during
+long-running processing, updates the ``delivered_at`` timestamp periodically to ensure
+the message is marked as "in progress".
+
+.. versionadded:: 7.3
+
+    Keepalive support, using the ``--keepalive`` option, was added in Symfony 7.3.
+
 Beanstalkd Transport
 ~~~~~~~~~~~~~~~~~~~~
 

From 57e4fcb84fd8b900d5f1f7203afb19451ff97672 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 31 Jan 2025 09:04:10 +0100
Subject: [PATCH 501/747] Minor tweak

---
 messenger.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index 727b1fbc39a..e5c4ccd9a17 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1699,7 +1699,7 @@ the message is marked as "in progress".
 
 .. versionadded:: 7.3
 
-    Keepalive support, using the ``--keepalive`` option, was added in Symfony 7.3.
+    Keepalive support, using the ``--keepalive`` option, was introduced in Symfony 7.3.
 
 Beanstalkd Transport
 ~~~~~~~~~~~~~~~~~~~~

From 1fc414588c7c7d78bd50b8177eca180d07d625b0 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 31 Jan 2025 09:28:34 +0100
Subject: [PATCH 502/747] Tweaks

---
 notifier.rst | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/notifier.rst b/notifier.rst
index 4c790125f3e..f240de44183 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -68,7 +68,7 @@ Service
 `AllMySms`_         **Install**: ``composer require symfony/all-my-sms-notifier`` \
                     **DSN**: ``allmysms://LOGIN:APIKEY@default?from=FROM`` \
                     **Webhook support**: No
-                    **SentMessage extra info**: `nbSms`, `balance`, `cost`
+                    **Extra properties in SentMessage**: ``nbSms``, ``balance``, ``cost``
 `AmazonSns`_        **Install**: ``composer require symfony/amazon-sns-notifier`` \
                     **DSN**: ``sns://ACCESS_KEY:SECRET_KEY@default?region=REGION`` \
                     **Webhook support**: No
@@ -140,7 +140,7 @@ Service
 `OvhCloud`_         **Install**: ``composer require symfony/ovh-cloud-notifier`` \
                     **DSN**: ``ovhcloud://APPLICATION_KEY:APPLICATION_SECRET@default?consumer_key=CONSUMER_KEY&service_name=SERVICE_NAME`` \
                     **Webhook support**: No
-                    **SentMessage extra info**: `totalCreditsRemoved`
+                    **Extra properties in SentMessage**:: ``totalCreditsRemoved``
 `Plivo`_            **Install**: ``composer require symfony/plivo-notifier`` \
                     **DSN**: ``plivo://AUTH_ID:AUTH_TOKEN@default?from=FROM`` \
                     **Webhook support**: No
@@ -241,6 +241,8 @@ Service
 .. versionadded:: 7.3
 
     Webhook support for the ``Brevo`` integration was introduced in Symfony 7.3.
+    The extra properties in ``SentMessage`` for ``AllMySms`` and ``OvhCloud``
+    providers were introduced in Symfony 7.3 too.
 
 .. deprecated:: 7.1
 

From 9f26f64863bb81880c0373f0c0efd0126a1a8712 Mon Sep 17 00:00:00 2001
From: Alsciende <bertolini.cedric@me.com>
Date: Sat, 19 Oct 2024 12:48:17 +0200
Subject: [PATCH 503/747] [Messenger] Add a tip about using
 `make:messenger-middleware`

---
 messenger.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index 217061d302c..cae1d795891 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2920,6 +2920,11 @@ and a different instance will be created per bus.
             $bus->middleware()->id('App\Middleware\AnotherMiddleware');
         };
 
+.. tip::
+
+    If you have installed the Maker bundle, you can use the ``make:messenger-middleware`` command
+    to bootstrap the creation your own messenger middleware.
+
 .. _middleware-doctrine:
 
 Middleware for Doctrine

From 2ed9ab1a6206290c5b843eabf9eb0434f7b2b1b9 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 3 Feb 2025 12:24:21 +0100
Subject: [PATCH 504/747] Minor tweak

---
 messenger.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index cae1d795891..d01ac3890fb 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2922,8 +2922,8 @@ and a different instance will be created per bus.
 
 .. tip::
 
-    If you have installed the Maker bundle, you can use the ``make:messenger-middleware`` command
-    to bootstrap the creation your own messenger middleware.
+    If you have installed the MakerBundle, you can use the ``make:messenger-middleware``
+    command to bootstrap the creation your own messenger middleware.
 
 .. _middleware-doctrine:
 

From 4ac85c1c5521a5933a64cadd591375fbc2b1fda3 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@qossmic.com>
Date: Tue, 4 Feb 2025 09:46:11 +0100
Subject: [PATCH 505/747] [#20337] fix typo

---
 messenger.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index 5458910d46a..e4f4abf60eb 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2925,7 +2925,7 @@ and a different instance will be created per bus.
 .. tip::
 
     If you have installed the MakerBundle, you can use the ``make:messenger-middleware``
-    command to bootstrap the creation your own messenger middleware.
+    command to bootstrap the creation of your own messenger middleware.
 
 .. _middleware-doctrine:
 

From da9ed9877aecbcb54fc97b61561ec018311ecff0 Mon Sep 17 00:00:00 2001
From: Alexis Urien <alexis.urien@free.fr>
Date: Thu, 6 Feb 2025 11:54:32 -0800
Subject: [PATCH 506/747] Update tags.rst

I think it's the new recommanded way for bundles (as seen here https://symfony.com/doc/current/bundles/extension.html)
---
 service_container/tags.rst | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/service_container/tags.rst b/service_container/tags.rst
index 270d6702f5a..fde9c2640aa 100644
--- a/service_container/tags.rst
+++ b/service_container/tags.rst
@@ -171,6 +171,25 @@ In a Symfony bundle, call this method in the ``load()`` method of the
         }
     }
 
+or if you are following the recommended way for new bundles and for bundles following the
+:ref:`recommended directory structure <bundles-directory-structure>`::
+
+    // ...
+    use Symfony\Component\DependencyInjection\ContainerBuilder;
+    use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
+    use Symfony\Component\HttpKernel\Bundle\AbstractBundle;
+    
+    class MyBundle extends AbstractBundle
+    {
+        public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void
+        {
+            $builder
+                ->registerForAutoconfiguration(CustomInterface::class)
+                ->addTag('app.custom_tag')
+            ;
+        }
+    }
+
 Autoconfiguration registering is not limited to interfaces. It is possible
 to use PHP attributes to autoconfigure services by using the
 :method:`Symfony\\Component\\DependencyInjection\\ContainerBuilder::registerAttributeForAutoconfiguration`

From 197da33b21c81dc6499d1735380e1117c83c6ee2 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Fri, 7 Feb 2025 09:14:45 +0100
Subject: [PATCH 507/747] [Validator] Add support for the `otherwise` option in
 the `When` constraint

---
 reference/constraints/When.rst | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/reference/constraints/When.rst b/reference/constraints/When.rst
index ec21eca9784..22ae477365f 100644
--- a/reference/constraints/When.rst
+++ b/reference/constraints/When.rst
@@ -9,6 +9,7 @@ Applies to  :ref:`class <validation-class-target>`
             or :ref:`property/method <validation-property-target>`
 Options     - `expression`_
             - `constraints`_
+            _ `otherwise`_
             - `groups`_
             - `payload`_
             - `values`_
@@ -47,7 +48,7 @@ properties::
 To validate the object, you have some requirements:
 
 A) If ``type`` is ``percent``, then ``value`` must be less than or equal 100;
-B) If ``type`` is ``absolute``, then ``value`` can be anything;
+B) If ``type`` is not ``percent``, then ``value`` must be less than 9999;
 C) No matter the value of ``type``, the ``value`` must be greater than 0.
 
 One way to accomplish this is with the When constraint:
@@ -69,6 +70,9 @@ One way to accomplish this is with the When constraint:
                 constraints: [
                     new Assert\LessThanOrEqual(100, message: 'The value should be between 1 and 100!')
                 ],
+                otherwise: [
+                    new Assert\LessThan(9999, message: 'The value should be less than 9999!')
+                ],
             )]
             private ?int $value;
 
@@ -88,6 +92,10 @@ One way to accomplish this is with the When constraint:
                             - LessThanOrEqual:
                                 value: 100
                                 message: "The value should be between 1 and 100!"
+                        otherwise:
+                            - LessThan:
+                                value: 9999
+                                message: "The value should be less than 9999!"
 
     .. code-block:: xml
 
@@ -109,6 +117,12 @@ One way to accomplish this is with the When constraint:
                                 <option name="message">The value should be between 1 and 100!</option>
                             </constraint>
                         </option>
+                        <option name="otherwise">
+                            <constraint name="LessThan">
+                                <option name="value">9999</option>
+                                <option name="message">The value should be less than 9999!</option>
+                            </constraint>
+                        </option>
                     </constraint>
                 </property>
             </class>
@@ -135,6 +149,12 @@ One way to accomplish this is with the When constraint:
                             message: 'The value should be between 1 and 100!',
                         ),
                     ],
+                    otherwise: [
+                        new Assert\LessThan(
+                            value: 9999,
+                            message: 'The value should be less than 9999!',
+                        ),
+                    ],
                 ));
             }
 
@@ -279,6 +299,17 @@ You can also pass custom variables using the `values`_ option.
 
 One or multiple constraints that are applied if the expression returns true.
 
+``otherwise``
+~~~~~~~~~~~~~
+
+**type**: ``array|Constraint``
+
+One or multiple constraints that are applied if the expression returns false.
+
+.. versionadded:: 7.3
+
+    The ``otherwise`` option was introduced in Symfony 7.3.
+
 .. include:: /reference/constraints/_groups-option.rst.inc
 
 .. include:: /reference/constraints/_payload-option.rst.inc

From cf1d8f176bc1a539ceaabc474485d833fa6291fe Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Tue, 11 Feb 2025 09:48:14 +0100
Subject: [PATCH 508/747] [FrameworkBundle] Allow to pass signals to
 `StopWorkerOnSignalsListener` in XML config and as plain strings

---
 messenger.rst | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 51 insertions(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index 8d679a48b61..2de8c6f9fb3 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -848,7 +848,56 @@ message before terminating.
 
 However, you might prefer to use different POSIX signals for graceful shutdown.
 You can override default ones by setting the ``framework.messenger.stop_worker_on_signals``
-configuration option.
+configuration option:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/messenger.yaml
+        framework:
+            messenger:
+                stop_worker_on_signals:
+                    - SIGTERM
+                    - SIGINT
+                    - SIGUSR1
+
+    .. code-block:: xml
+
+        <!-- config/packages/messenger.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                   xmlns:framework="http://symfony.com/schema/dic/symfony"
+                   xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <framework:config>
+                <framework:messenger>
+                    <!-- ... -->
+                    <framework:stop-worker-on-signal>SIGTERM</framework:stop-worker-on-signal>
+                    <framework:stop-worker-on-signal>SIGINT</framework:stop-worker-on-signal>
+                    <framework:stop-worker-on-signal>SIGUSR1</framework:stop-worker-on-signal>
+                </framework:messenger>
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/messenger.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            $framework->messenger()
+                ->stopWorkerOnSignals(['SIGTERM', 'SIGINT', 'SIGUSR1']);
+        };
+
+.. versionadded:: 7.3
+
+    Support for signals plain name in configuration was introduced in Symfony 7.3.
+    Prior to this, you had to use the numeric values of the signals as defined
+    in the ``pcntl`` extension's `predefined constants`_.
 
 In some cases the ``SIGTERM`` signal is sent by Supervisor itself (e.g. stopping
 a Docker container having Supervisor as its entrypoint). In these cases you
@@ -3587,3 +3636,4 @@ Learn more
 .. _`high connection churn`: https://www.rabbitmq.com/connections.html#high-connection-churn
 .. _`article about CQRS`: https://martinfowler.com/bliki/CQRS.html
 .. _`SSL context options`: https://php.net/context.ssl
+.. _`predefined constants`: https://www.php.net/pcntl.constants

From 3de90f363a446bb0d675c110c7529014e45604c7 Mon Sep 17 00:00:00 2001
From: Hugo Alliaume <hugo@alliau.me>
Date: Tue, 11 Feb 2025 15:52:18 +0100
Subject: [PATCH 509/747] [Cache] Fix "Marshalling (Serializing) Data" code
 rendering issue

---
 components/cache.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/components/cache.rst b/components/cache.rst
index 939627b1807..4873fb7abc7 100644
--- a/components/cache.rst
+++ b/components/cache.rst
@@ -209,11 +209,11 @@ the cache items before storing them.
 
 The :class:`Symfony\\Component\\Cache\\Marshaller\\DefaultMarshaller` uses PHP's
 ``serialize()`` function by default, but you can optionally use the ``igbinary_serialize()``
-function from the `Igbinary extension`_:
+function from the `Igbinary extension`_::
 
     use Symfony\Component\Cache\Adapter\RedisAdapter;
-    use Symfony\Component\Cache\DefaultMarshaller;
-    use Symfony\Component\Cache\DeflateMarshaller;
+    use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
+    use Symfony\Component\Cache\Marshaller\DeflateMarshaller;
 
     $marshaller = new DeflateMarshaller(new DefaultMarshaller());
     // you can optionally use the Igbinary extension if you have it installed

From 08a3431263166a0bd2e889b026601abeddeb1c14 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 12 Feb 2025 08:40:52 +0100
Subject: [PATCH 510/747] Minor tweaks

---
 messenger.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index 2de8c6f9fb3..c6643af0a89 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -895,9 +895,9 @@ configuration option:
 
 .. versionadded:: 7.3
 
-    Support for signals plain name in configuration was introduced in Symfony 7.3.
-    Prior to this, you had to use the numeric values of the signals as defined
-    in the ``pcntl`` extension's `predefined constants`_.
+    Support for signals plain names in configuration was introduced in Symfony 7.3.
+    Previously, you had to use the numeric values of signals as defined by the
+    ``pcntl`` extension's `predefined constants`_.
 
 In some cases the ``SIGTERM`` signal is sent by Supervisor itself (e.g. stopping
 a Docker container having Supervisor as its entrypoint). In these cases you

From 37e23491022c0440573378809b964b0eacc848a9 Mon Sep 17 00:00:00 2001
From: Florent Morselli <florent.morselli@spomky-labs.com>
Date: Thu, 13 Feb 2025 09:36:07 +0100
Subject: [PATCH 511/747] Add `role_fetcher` option to LDAP security
 configuration

The `role_fetcher` option allows defining a service to fetch user roles from the LDAP server by implementing `RoleFetcherInterface`. This option was introduced in Symfony 7.3, and it supersedes `default_roles` when set. The `MemberOfRoles` implementation can be used to retrieve roles from the `ismemberof` attribute.
---
 security/ldap.rst | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/security/ldap.rst b/security/ldap.rst
index 081be764290..923d74807dc 100644
--- a/security/ldap.rst
+++ b/security/ldap.rst
@@ -256,6 +256,23 @@ This is the default role you wish to give to a user fetched from the LDAP
 server. If you do not configure this key, your users won't have any roles,
 and will not be considered as authenticated fully.
 
+role_fetcher
+............
+
+**type**: ``string`` **default**: ``null``
+
+When your LDAP service provides user roles, you can use this configuration option
+to define the role fetcher service. The role fetcher service must implement the
+``Component\Ldap\Security\RoleFetcherInterface`` interface.
+``default_roles`` is ignored when ``role_fetcher`` is set.
+
+``Symfony\Component\Ldap\Security\MemberOfRoles`` is a concrete implementation
+of the ``RoleFetcherInterface`` that fetches roles from the ``ismemberof`` attribute.
+
+.. versionadded:: 7.3
+
+    The configuration option ``role_fetcher`` was introduced in Symfony 7.3.
+
 uid_key
 .......
 

From 85b4530e81355182d6ad59fac60f9d8c0459e2de Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 14 Feb 2025 09:16:31 +0100
Subject: [PATCH 512/747] Minor tweaks

---
 security/ldap.rst | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/security/ldap.rst b/security/ldap.rst
index 923d74807dc..c4c3646122b 100644
--- a/security/ldap.rst
+++ b/security/ldap.rst
@@ -259,19 +259,20 @@ and will not be considered as authenticated fully.
 role_fetcher
 ............
 
-**type**: ``string`` **default**: ``null``
+**Type**: ``string`` **Default**: ``null``
 
-When your LDAP service provides user roles, you can use this configuration option
-to define the role fetcher service. The role fetcher service must implement the
-``Component\Ldap\Security\RoleFetcherInterface`` interface.
-``default_roles`` is ignored when ``role_fetcher`` is set.
+When your LDAP service provides user roles, this option allows you to define
+the service that retrieves these roles. The role fetcher service must implement
+the ``Symfony\Component\Ldap\Security\RoleFetcherInterface``. When this option
+is set, the ``default_roles`` option is ignored.
 
-``Symfony\Component\Ldap\Security\MemberOfRoles`` is a concrete implementation
-of the ``RoleFetcherInterface`` that fetches roles from the ``ismemberof`` attribute.
+Symfony provides ``Symfony\Component\Ldap\Security\MemberOfRoles``, a concrete
+implementation of the interface that fetches roles from the ``ismemberof``
+attribute.
 
 .. versionadded:: 7.3
 
-    The configuration option ``role_fetcher`` was introduced in Symfony 7.3.
+    The ``role_fetcher`` configuration option was introduced in Symfony 7.3.
 
 uid_key
 .......

From 3b1505d8f6dedb3d1feb5d56ea1ad74a93dcb8a5 Mon Sep 17 00:00:00 2001
From: Kirill Kotov <k.kotov@codd.tech>
Date: Sat, 15 Feb 2025 12:38:18 +0300
Subject: [PATCH 513/747] Messenger: Add consumer name documentation

---
 messenger.rst | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index e4f4abf60eb..c62436eb1e9 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1768,7 +1768,21 @@ under the transport in ``messenger.yaml``:
     The Redis consumer group name
 
 ``consumer`` (default: ``consumer``)
-    Consumer name used in Redis
+    Consumer name used in Redis. Allows to set explicit consumer name identifier.
+    Recommended for environments with multiple workers to prevent duplicate message processing.
+    Typically set via environment variable:
+
+    .. code-block:: yaml
+
+        # config/packages/messenger.yaml
+        framework:
+            messenger:
+                transports:
+                    redis:
+                        dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
+                        options:
+                            consumer: '%env(MESSENGER_CONSUMER_NAME)%'
+
 
 ``auto_setup`` (default: ``true``)
     Whether to create the Redis group automatically

From 03b1ed9d422b12e12c9673dd9934090127b8bc8c Mon Sep 17 00:00:00 2001
From: Frank Schulze <frank@akiber.de>
Date: Wed, 8 Jan 2025 18:32:15 +0100
Subject: [PATCH 514/747] [Notifier] Add Matrix bridge

---
 notifier.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/notifier.rst b/notifier.rst
index 090f4db2007..da0a622fb1d 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -369,6 +369,7 @@ Service                                  Package                               D
 `LinkedIn`_                              ``symfony/linked-in-notifier``        ``linkedin://TOKEN:USER_ID@default``
 `Mastodon`_                              ``symfony/mastodon-notifier``         ``mastodon://ACCESS_TOKEN@HOST``
 `Mattermost`_                            ``symfony/mattermost-notifier``       ``mattermost://ACCESS_TOKEN@HOST/PATH?channel=CHANNEL``
+`Matrix`_                                ``symfony/matrix-notifier``           ``matrix://HOST:PORT/?accessToken=ACCESSTOKEN&ssl=SSL``
 `Mercure`_                               ``symfony/mercure-notifier``          ``mercure://HUB_ID?topic=TOPIC``
 `MicrosoftTeams`_                        ``symfony/microsoft-teams-notifier``  ``microsoftteams://default/PATH``
 `RocketChat`_                            ``symfony/rocket-chat-notifier``      ``rocketchat://TOKEN@ENDPOINT?channel=CHANNEL``
@@ -392,6 +393,10 @@ Service                                  Package                               D
     The ``Gitter`` integration was removed in Symfony 7.2 because that service
     no longer provides an API.
 
+.. versionadded:: 7.3
+
+    The ``Matrix`` integration was introduced in Symfony 7.3.
+
 .. warning::
 
     By default, if you have the :doc:`Messenger component </messenger>` installed,
@@ -1259,6 +1264,7 @@ is dispatched. Listeners receive a
 .. _`LOX24`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Lox24/README.md
 .. _`Mailjet`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Mailjet/README.md
 .. _`Mastodon`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Mastodon/README.md
+.. _`Matrix`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Matrix/README.md
 .. _`Mattermost`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Mattermost/README.md
 .. _`Mercure`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/Mercure/README.md
 .. _`MessageBird`: https://github.com/symfony/symfony/blob/{version}/src/Symfony/Component/Notifier/Bridge/MessageBird/README.md

From 2f957375486c4aa8e15733987d987738aa0c34f2 Mon Sep 17 00:00:00 2001
From: Alexander Menk <a.menk@imi.de>
Date: Fri, 14 Feb 2025 14:42:17 +0100
Subject: [PATCH 515/747] [Console] Add markdown format to Table

---
 components/console/helpers/table.rst | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/components/console/helpers/table.rst b/components/console/helpers/table.rst
index 13bdeb491f0..1f90512af7b 100644
--- a/components/console/helpers/table.rst
+++ b/components/console/helpers/table.rst
@@ -181,11 +181,27 @@ The table style can be changed to any built-in styles via
     // same as calling nothing
     $table->setStyle('default');
 
-    // changes the default style to compact
+    // changes the default style to markdown
+    $table->setStyle('markdown');
+    $table->render();
+
+This outputs the table in the Markdown format:
+
+.. code-block:: terminal
+
+    | ISBN          | Title                    | Author           |
+    |---------------|--------------------------|------------------|
+    | 99921-58-10-7 | Divine Comedy            | Dante Alighieri  |
+    | 9971-5-0210-0 | A Tale of Two Cities     | Charles Dickens  |
+    | 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
+    | 80-902734-1-6 | And Then There Were None | Agatha Christie  |
+
+You can also set the style to ``compact``::
+
     $table->setStyle('compact');
     $table->render();
 
-This code results in:
+The output of this command will be:
 
 .. code-block:: terminal
 

From 0f887b0c50b7b93a1eed0c2547f951f11a669630 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 17 Feb 2025 08:32:39 +0100
Subject: [PATCH 516/747] Added the versionadded directive

---
 components/console/helpers/table.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/components/console/helpers/table.rst b/components/console/helpers/table.rst
index 1f90512af7b..9d6fdb0ee61 100644
--- a/components/console/helpers/table.rst
+++ b/components/console/helpers/table.rst
@@ -196,6 +196,10 @@ This outputs the table in the Markdown format:
     | 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
     | 80-902734-1-6 | And Then There Were None | Agatha Christie  |
 
+.. versionadded:: 7.3
+
+    The ``markdown`` style was introduced in Symfony 7.3.
+
 You can also set the style to ``compact``::
 
     $table->setStyle('compact');

From 2af4cbece3c63074ea77e2a3bae2717b03c89e07 Mon Sep 17 00:00:00 2001
From: Sherin Bloemendaal <sherinbloemendaal@outlook.com>
Date: Mon, 17 Feb 2025 15:27:01 +0100
Subject: [PATCH 517/747] Remove per-property support, dropped in Symfony 7.0

---
 components/var_exporter.rst | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/components/var_exporter.rst b/components/var_exporter.rst
index 6aa4279788e..fc6b34868db 100644
--- a/components/var_exporter.rst
+++ b/components/var_exporter.rst
@@ -264,17 +264,6 @@ While you never query ``$processor->hash`` value, heavy methods will never be
 triggered. But still, the ``$processor`` object exists and can be used in your
 code, passed to methods, functions, etc.
 
-Additionally and by adding two arguments to the initializer function, it is
-possible to initialize properties one-by-one::
-
-    $processor = LazyHashProcessor::createLazyGhost(initializer: function (HashProcessor $instance, string $propertyName, ?string $propertyScope): mixed {
-        if (HashProcessor::class === $propertyScope && 'hash' === $propertyName) {
-            // Return $hash value
-        }
-
-        // Then you can add more logic for the other properties
-    });
-
 Ghost objects unfortunately can't work with abstract classes or internal PHP
 classes. Nevertheless, the VarExporter component covers this need with the help
 of :ref:`Virtual Proxies <var-exporter_virtual-proxies>`.

From 044c5aa27a5838109efe5572d0cf910bb9dac614 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 18 Feb 2025 08:22:00 +0100
Subject: [PATCH 518/747] Add a deprecation notice

---
 components/var_exporter.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/components/var_exporter.rst b/components/var_exporter.rst
index fc6b34868db..e4d01ee6ecf 100644
--- a/components/var_exporter.rst
+++ b/components/var_exporter.rst
@@ -260,6 +260,11 @@ convert non-lazy classes to lazy ones::
         $instance->validateHash();
     });
 
+.. deprecated:: 7.0
+
+    The ``initializer`` function allowed passing two arguments to it to initialize
+    properties one by one. This feature was removed in Symfony 7.0.
+
 While you never query ``$processor->hash`` value, heavy methods will never be
 triggered. But still, the ``$processor`` object exists and can be used in your
 code, passed to methods, functions, etc.

From 659937bf44de6b414936d27bebd9f5818fad6b05 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 18 Feb 2025 17:08:11 +0100
Subject: [PATCH 519/747] [Notifier] Reformat the tables that list the service
 integrations

---
 notifier.rst | 110 ++++++++++++++++++++++++++++++++-------------------
 1 file changed, 69 insertions(+), 41 deletions(-)

diff --git a/notifier.rst b/notifier.rst
index 36fbd5ada89..2382dfee284 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -350,30 +350,50 @@ 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
-=======================================  ====================================  =============================================================================
-`AmazonSns`_                             ``symfony/amazon-sns-notifier``       ``sns://ACCESS_KEY:SECRET_KEY@default?region=REGION``
-`Bluesky`_                               ``symfony/bluesky-notifier``          ``bluesky://USERNAME:PASSWORD@default``
-`Chatwork`_                              ``symfony/chatwork-notifier``         ``chatwork://API_TOKEN@default?room_id=ID``
-`Discord`_                               ``symfony/discord-notifier``          ``discord://TOKEN@default?webhook_id=ID``
-`FakeChat`_                              ``symfony/fake-chat-notifier``        ``fakechat+email://default?to=TO&from=FROM`` or ``fakechat+logger://default``
-`Firebase`_                              ``symfony/firebase-notifier``         ``firebase://USERNAME:PASSWORD@default``
-`GoogleChat`_                            ``symfony/google-chat-notifier``      ``googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?thread_key=THREAD_KEY``
-`LINE Bot`_                              ``symfony/line-bot-notifier``         ``linebot://TOKEN@default?receiver=RECEIVER``
-`LINE Notify`_                           ``symfony/line-notify-notifier``      ``linenotify://TOKEN@default``
-`LinkedIn`_                              ``symfony/linked-in-notifier``        ``linkedin://TOKEN:USER_ID@default``
-`Mastodon`_                              ``symfony/mastodon-notifier``         ``mastodon://ACCESS_TOKEN@HOST``
-`Mattermost`_                            ``symfony/mattermost-notifier``       ``mattermost://ACCESS_TOKEN@HOST/PATH?channel=CHANNEL``
-`Mercure`_                               ``symfony/mercure-notifier``          ``mercure://HUB_ID?topic=TOPIC``
-`MicrosoftTeams`_                        ``symfony/microsoft-teams-notifier``  ``microsoftteams://default/PATH``
-`RocketChat`_                            ``symfony/rocket-chat-notifier``      ``rocketchat://TOKEN@ENDPOINT?channel=CHANNEL``
-`Slack`_                                 ``symfony/slack-notifier``            ``slack://TOKEN@default?channel=CHANNEL``
-`Telegram`_                              ``symfony/telegram-notifier``         ``telegram://TOKEN@default?channel=CHAT_ID``
-`Twitter`_                               ``symfony/twitter-notifier``          ``twitter://API_KEY:API_SECRET:ACCESS_TOKEN:ACCESS_SECRET@default``
-`Zendesk`_                               ``symfony/zendesk-notifier``          ``zendesk://EMAIL:TOKEN@SUBDOMAIN``
-`Zulip`_                                 ``symfony/zulip-notifier``            ``zulip://EMAIL:TOKEN@HOST?channel=CHANNEL``
-======================================   ====================================  =============================================================================
+======================================   =====================================================================================
+Service
+======================================   =====================================================================================
+`AmazonSns`_                             **Install**: ``composer require symfony/amazon-sns-notifier`` \
+                                         **DSN**: ``sns://ACCESS_KEY:SECRET_KEY@default?region=REGION``
+`Bluesky`_                               **Install**: ``composer require symfony/bluesky-notifier`` \
+                                         **DSN**: ``bluesky://USERNAME:PASSWORD@default``
+`Chatwork`_                              **Install**: ``composer require symfony/chatwork-notifier`` \
+                                         **DSN**: ``chatwork://API_TOKEN@default?room_id=ID``
+`Discord`_                               **Install**: ``composer require symfony/discord-notifier`` \
+                                         **DSN**: ``discord://TOKEN@default?webhook_id=ID``
+`FakeChat`_                              **Install**: ``composer require symfony/fake-chat-notifier`` \
+                                         **DSN**: ``fakechat+email://default?to=TO&from=FROM`` or ``fakechat+logger://default``
+`Firebase`_                              **Install**: ``composer require symfony/firebase-notifier`` \
+                                         **DSN**: ``firebase://USERNAME:PASSWORD@default``
+`GoogleChat`_                            **Install**: ``composer require symfony/google-chat-notifier`` \
+                                         **DSN**: ``googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?thread_key=THREAD_KEY``
+`LINE Bot`_                              **Install**: ``composer require symfony/line-bot-notifier`` \
+                                         **DSN**: ``linebot://TOKEN@default?receiver=RECEIVER``
+`LINE Notify`_                           **Install**: ``composer require symfony/line-notify-notifier`` \
+                                         **DSN**: ``linenotify://TOKEN@default``
+`LinkedIn`_                              **Install**: ``composer require symfony/linked-in-notifier`` \
+                                         **DSN**: ``linkedin://TOKEN:USER_ID@default``
+`Mastodon`_                              **Install**: ``composer require symfony/mastodon-notifier`` \
+                                         **DSN**: ``mastodon://ACCESS_TOKEN@HOST``
+`Mattermost`_                            **Install**: ``composer require symfony/mattermost-notifier`` \
+                                         **DSN**: ``mattermost://ACCESS_TOKEN@HOST/PATH?channel=CHANNEL``
+`Mercure`_                               **Install**: ``composer require symfony/mercure-notifier`` \
+                                         **DSN**: ``mercure://HUB_ID?topic=TOPIC``
+`MicrosoftTeams`_                        **Install**: ``composer require symfony/microsoft-teams-notifier`` \
+                                         **DSN**: ``microsoftteams://default/PATH``
+`RocketChat`_                            **Install**: ``composer require symfony/rocket-chat-notifier`` \
+                                         **DSN**: ``rocketchat://TOKEN@ENDPOINT?channel=CHANNEL``
+`Slack`_                                 **Install**: ``composer require symfony/slack-notifier`` \
+                                         **DSN**: ``slack://TOKEN@default?channel=CHANNEL``
+`Telegram`_                              **Install**: ``composer require symfony/telegram-notifier`` \
+                                         **DSN**: ``telegram://TOKEN@default?channel=CHAT_ID``
+`Twitter`_                               **Install**: ``composer require symfony/twitter-notifier`` \
+                                         **DSN**: ``twitter://API_KEY:API_SECRET:ACCESS_TOKEN:ACCESS_SECRET@default``
+`Zendesk`_                               **Install**: ``composer require symfony/zendesk-notifier`` \
+                                         **DSN**: ``zendesk://EMAIL:TOKEN@SUBDOMAIN``
+`Zulip`_                                 **Install**: ``composer require symfony/zulip-notifier`` \
+                                         **DSN**: ``zulip://EMAIL:TOKEN@HOST?channel=CHANNEL``
+======================================   =====================================================================================
 
 .. versionadded:: 7.1
 
@@ -569,18 +589,26 @@ The push channel is used to send notifications to users by using
 :class:`Symfony\\Component\\Notifier\\Texter` classes. Symfony provides
 integration with these push services:
 
-===============  ====================================  ==============================================================================
-Service          Package                               DSN
-===============  ====================================  ==============================================================================
-`Engagespot`_    ``symfony/engagespot-notifier``       ``engagespot://API_KEY@default?campaign_name=CAMPAIGN_NAME``
-`Expo`_          ``symfony/expo-notifier``             ``expo://Token@default``
-`Novu`_          ``symfony/novu-notifier``             ``novu://API_KEY@default``
-`Ntfy`_          ``symfony/ntfy-notifier``             ``ntfy://default/TOPIC``
-`OneSignal`_     ``symfony/one-signal-notifier``       ``onesignal://APP_ID:API_KEY@default?defaultRecipientId=DEFAULT_RECIPIENT_ID``
-`PagerDuty`_     ``symfony/pager-duty-notifier``       ``pagerduty://TOKEN@SUBDOMAIN``
-`Pushover`_      ``symfony/pushover-notifier``         ``pushover://USER_KEY:APP_TOKEN@default``
-`Pushy`_         ``symfony/pushy-notifier``            ``pushy://API_KEY@default``
-===============  ====================================  ==============================================================================
+===============  =======================================================================================
+Service
+===============  =======================================================================================
+`Engagespot`_    **Install**: ``composer require symfony/engagespot-notifier`` \
+                 **DSN**: ``engagespot://API_KEY@default?campaign_name=CAMPAIGN_NAME``
+`Expo`_          **Install**: ``composer require symfony/expo-notifier`` \
+                 **DSN**: ``expo://TOKEN@default``
+`Novu`_          **Install**: ``composer require symfony/novu-notifier`` \
+                 **DSN**: ``novu://API_KEY@default``
+`Ntfy`_          **Install**: ``composer require symfony/ntfy-notifier`` \
+                 **DSN**: ``ntfy://default/TOPIC``
+`OneSignal`_     **Install**: ``composer require symfony/one-signal-notifier`` \
+                 **DSN**: ``onesignal://APP_ID:API_KEY@default?defaultRecipientId=DEFAULT_RECIPIENT_ID``
+`PagerDuty`_     **Install**: ``composer require symfony/pager-duty-notifier`` \
+                 **DSN**: ``pagerduty://TOKEN@SUBDOMAIN``
+`Pushover`_      **Install**: ``composer require symfony/pushover-notifier`` \
+                 **DSN**: ``pushover://USER_KEY:APP_TOKEN@default``
+`Pushy`_         **Install**: ``composer require symfony/pushy-notifier`` \
+                 **DSN**: ``pushy://API_KEY@default``
+===============  =======================================================================================
 
 To enable a texter, add the correct DSN in your ``.env`` file and
 configure the ``texter_transports``:
@@ -645,11 +673,11 @@ The desktop channel is used to display local desktop notifications on the same
 host machine using :class:`Symfony\\Component\\Notifier\\Texter` classes. Currently,
 Symfony is integrated with the following providers:
 
-===============  ====================================  ==============================================================================
-Provider         Package                               DSN
-===============  ====================================  ==============================================================================
-`JoliNotif`_     ``symfony/joli-notif-notifier``       ``jolinotif://default``
-===============  ====================================  ==============================================================================
+===============  ================================================  ==============================================================================
+Provider         Install                                           DSN
+===============  ================================================  ==============================================================================
+`JoliNotif`_     ``composer require symfony/joli-notif-notifier``  ``jolinotif://default``
+===============  ================================================  ==============================================================================
 
 .. versionadded:: 7.2
 

From 764e47d2fff954f9efe474264c53cb566bed4f6b Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 19 Feb 2025 11:58:00 +0100
Subject: [PATCH 520/747] [Notifier] Mention the extra info returned in Bluesky
 SentMessage

---
 notifier.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/notifier.rst b/notifier.rst
index 2a5877ee465..ebd2602328c 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -365,6 +365,7 @@ Service
                                          **DSN**: ``sns://ACCESS_KEY:SECRET_KEY@default?region=REGION``
 `Bluesky`_                               **Install**: ``composer require symfony/bluesky-notifier`` \
                                          **DSN**: ``bluesky://USERNAME:PASSWORD@default``
+                                         **Extra properties in SentMessage**:: ``cid``
 `Chatwork`_                              **Install**: ``composer require symfony/chatwork-notifier`` \
                                          **DSN**: ``chatwork://API_TOKEN@default?room_id=ID``
 `Discord`_                               **Install**: ``composer require symfony/discord-notifier`` \

From 4ddcc0829b6a68763e8105c38da96ca456669f36 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 19 Feb 2025 13:15:33 +0100
Subject: [PATCH 521/747] [Security] Add support for closures in the
 `IsGranted` attribute

---
 security/expressions.rst | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/security/expressions.rst b/security/expressions.rst
index 569c7f093bf..dce52ee74ff 100644
--- a/security/expressions.rst
+++ b/security/expressions.rst
@@ -201,6 +201,41 @@ Inside the subject's expression, you have access to two variables:
 ``args``
     An array of controller arguments that are passed to the controller.
 
+Additionally to expressions, the ``#[IsGranted]`` attribute also accepts
+closures that return a boolean value. The subject can also be a closure that
+returns an array of values that will be injected into the closure::
+
+    // src/Controller/MyController.php
+    namespace App\Controller;
+
+    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+    use Symfony\Component\HttpFoundation\Response;
+    use Symfony\Component\Security\Http\Attribute\IsGranted;
+    use Symfony\Component\Security\Http\Attribute\IsGrantedContext;
+
+    class MyController extends AbstractController
+    {
+        #[IsGranted(static function (
+            IsGrantedContext $context,
+            mixed $subject,
+        ) {
+            return $context->user === $subject['post']->getAuthor();
+        }, subject: static function (array $args) {
+            return [
+                'post' => $args['post'],
+            ];
+        })]
+        public function index($post): Response
+        {
+            // ...
+        }
+    }
+
+.. versionadded:: 7.3
+
+    The support for closures in the ``#[IsGranted]`` attribute was introduced
+    in Symfony 7.3 and requires PHP 8.5.
+
 Learn more
 ----------
 

From 60726ca2729218286082d64c6b4fd3f10c55bf07 Mon Sep 17 00:00:00 2001
From: Pierre Ambroise <pierre27.ambroise@gmail.com>
Date: Thu, 20 Feb 2025 08:49:25 +0100
Subject: [PATCH 522/747] Add missing spaces in scheduler

---
 scheduler.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/scheduler.rst b/scheduler.rst
index 5bac82d98ae..271117f97dc 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -436,10 +436,10 @@ by adding one of these attributes to a service or a command:
 :class:`Symfony\\Component\\Scheduler\\Attribute\\AsCronTask`.
 
 For both of these attributes, you have the ability to define the schedule to
-use via the ``schedule``option. By default, the ``default`` named schedule will
+use via the ``schedule`` option. By default, the ``default`` named schedule will
 be used. Also, by default, the ``__invoke`` method of your service will be called
-but, it's also possible to specify the method to call via the ``method``option
-and you can define arguments via ``arguments``option if necessary.
+but, it's also possible to specify the method to call via the ``method`` option
+and you can define arguments via ``arguments`` option if necessary.
 
 .. _scheduler-attributes-cron-task:
 

From 67fd89cc7d7dbc756b1403ccc94060462ff786c4 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 20 Feb 2025 09:02:04 +0100
Subject: [PATCH 523/747] Minor typo

---
 notifier.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/notifier.rst b/notifier.rst
index ebd2602328c..33ae95ef9e4 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -365,7 +365,7 @@ Service
                                          **DSN**: ``sns://ACCESS_KEY:SECRET_KEY@default?region=REGION``
 `Bluesky`_                               **Install**: ``composer require symfony/bluesky-notifier`` \
                                          **DSN**: ``bluesky://USERNAME:PASSWORD@default``
-                                         **Extra properties in SentMessage**:: ``cid``
+                                         **Extra properties in SentMessage**: ``cid``
 `Chatwork`_                              **Install**: ``composer require symfony/chatwork-notifier`` \
                                          **DSN**: ``chatwork://API_TOKEN@default?room_id=ID``
 `Discord`_                               **Install**: ``composer require symfony/discord-notifier`` \

From 06e15d5555360305ace149aa2550c62682b6d36d Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Thu, 20 Feb 2025 12:59:49 +0100
Subject: [PATCH 524/747] [Validator] Add support for closures in the `When`
 constraint

---
 reference/constraints/When.rst | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/reference/constraints/When.rst b/reference/constraints/When.rst
index 22ae477365f..2674972a023 100644
--- a/reference/constraints/When.rst
+++ b/reference/constraints/When.rst
@@ -174,11 +174,12 @@ Options
 ``expression``
 ~~~~~~~~~~~~~~
 
-**type**: ``string``
+**type**: ``string|Closure``
 
-The condition written with the expression language syntax that will be evaluated.
-If the expression evaluates to a falsey value (i.e. using ``==``, not ``===``),
-validation of constraints won't be triggered.
+The condition as a closure or written with the expression language syntax
+that will be evaluated. If the closure return value or the evaluated expression
+is a falsey value (i.e. using ``==``, not ``===``), validation of constraints won't
+be triggered, and constraints of the ``otherwise`` option will, if provided.
 
 To learn more about the expression language syntax, see
 :doc:`/reference/formats/expression_language`.
@@ -200,6 +201,13 @@ in your expression:
 
     The ``context`` variable in expressions was introduced in Symfony 7.2.
 
+When using a closure, the first argument is the object being validated.
+
+.. versionadded:: 7.3
+
+    The support for closure in the ``expression`` option was introduced in Symfony 7.3
+    and requires PHP 8.5.
+
 The ``value`` variable can be used when you want to execute more complex
 validation based on its value:
 
@@ -215,11 +223,20 @@ validation based on its value:
 
         class Discount
         {
+            // either using an expression...
             #[Assert\When(
                 expression: 'value == "percent"',
                 constraints: [new Assert\Callback('doComplexValidation')],
             )]
+            // ... or using a closure
+            #[Assert\When(
+                expression: static function (Discount $discount) {
+                    return $discount->getType() === 'percent';
+                },
+                constraints: [new Assert\Callback('doComplexValidation')],
+            )]
             private ?string $type;
+
             // ...
 
             public function doComplexValidation(ExecutionContextInterface $context, $payload): void

From ec3d995f1c5a788d9749e33bcacce4938da82a82 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 21 Feb 2025 16:27:15 +0100
Subject: [PATCH 525/747] Minor tweaks

---
 reference/constraints/When.rst | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/reference/constraints/When.rst b/reference/constraints/When.rst
index 2674972a023..7587f0c776c 100644
--- a/reference/constraints/When.rst
+++ b/reference/constraints/When.rst
@@ -176,16 +176,13 @@ Options
 
 **type**: ``string|Closure``
 
-The condition as a closure or written with the expression language syntax
-that will be evaluated. If the closure return value or the evaluated expression
-is a falsey value (i.e. using ``==``, not ``===``), validation of constraints won't
-be triggered, and constraints of the ``otherwise`` option will, if provided.
+The condition evaluated to decide if the constraint is applied or not. It can be
+defined as a closure or a string using the :doc:`expression language syntax </reference/formats/expression_language>`.
+If the result is a falsey value (``false``, ``null``, ``0``, an empty string or
+an empty array) the constraints defined in the ``constraints`` option won't be
+applied but the constraints defined in ``otherwise`` option (if provided) will be applied.
 
-To learn more about the expression language syntax, see
-:doc:`/reference/formats/expression_language`.
-
-Depending on how you use the constraint, you have access to different variables
-in your expression:
+**When using an expression**, you access to the following variables:
 
 ``this``
     The object being validated (e.g. an instance of Discount).
@@ -201,16 +198,13 @@ in your expression:
 
     The ``context`` variable in expressions was introduced in Symfony 7.2.
 
-When using a closure, the first argument is the object being validated.
+**When using a closure**, the first argument is the object being validated.
 
 .. versionadded:: 7.3
 
     The support for closure in the ``expression`` option was introduced in Symfony 7.3
     and requires PHP 8.5.
 
-The ``value`` variable can be used when you want to execute more complex
-validation based on its value:
-
 .. configuration-block::
 
     .. code-block:: php-attributes
@@ -228,6 +222,7 @@ validation based on its value:
                 expression: 'value == "percent"',
                 constraints: [new Assert\Callback('doComplexValidation')],
             )]
+
             // ... or using a closure
             #[Assert\When(
                 expression: static function (Discount $discount) {

From f49a48a5b74a43d6da63b7300ca473dd59327e8f Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 21 Feb 2025 16:28:02 +0100
Subject: [PATCH 526/747] Minor fix

---
 reference/constraints/When.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/constraints/When.rst b/reference/constraints/When.rst
index 7587f0c776c..6eca8b4895f 100644
--- a/reference/constraints/When.rst
+++ b/reference/constraints/When.rst
@@ -202,7 +202,7 @@ applied but the constraints defined in ``otherwise`` option (if provided) will b
 
 .. versionadded:: 7.3
 
-    The support for closure in the ``expression`` option was introduced in Symfony 7.3
+    The support for closures in the ``expression`` option was introduced in Symfony 7.3
     and requires PHP 8.5.
 
 .. configuration-block::

From 7f701e7c6e29b9e34bc2753f9dcf021244af5259 Mon Sep 17 00:00:00 2001
From: Peter Trebaticky <github.10.trepe@spamgourmet.com>
Date: Fri, 21 Feb 2025 18:56:19 +0100
Subject: [PATCH 527/747] [Messenger] Add options to specify SQS queue
 attributes and tags

---
 messenger.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index c6643af0a89..477ef65b740 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2064,6 +2064,12 @@ The transport has a number of options:
 ``queue_name`` (default: ``messages``)
     Name of the queue
 
+``queue_attributes``
+    Attributes of a queue as per `SQS CreateQueue API`_. Array of strings indexed by keys of ``AsyncAws\Sqs\Enum\QueueAttributeName``. Added in Symfony 7.3.
+
+``queue_tags``
+    Cost allocation tags of a queue as per `SQS CreateQueue API`_. Array of strings indexed by strings. Added in Symfony 7.3.
+
 ``region`` (default: ``eu-west-1``)
     Name of the AWS region
 
@@ -3637,3 +3643,4 @@ Learn more
 .. _`article about CQRS`: https://martinfowler.com/bliki/CQRS.html
 .. _`SSL context options`: https://php.net/context.ssl
 .. _`predefined constants`: https://www.php.net/pcntl.constants
+.. _`SQS CreateQueue API`: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_CreateQueue.html

From b3b790157e0fd9bcdc57f98988288d68dcbb0336 Mon Sep 17 00:00:00 2001
From: Fabien Potencier <fabien@potencier.org>
Date: Mon, 24 Feb 2025 15:18:40 +0100
Subject: [PATCH 528/747] Move the core team page to the contributing root dir
 as it's not just about code

---
 _build/redirection_map                     | 1 +
 _images/sources/README.md                  | 2 +-
 contributing/code/index.rst                | 1 -
 contributing/code/pull_requests.rst        | 2 +-
 contributing/code/standards.rst            | 2 +-
 contributing/code_of_conduct/care_team.rst | 2 +-
 contributing/community/releases.rst        | 2 +-
 contributing/{code => }/core_team.rst      | 0
 contributing/map.rst.inc                   | 3 ++-
 9 files changed, 8 insertions(+), 7 deletions(-)
 rename contributing/{code => }/core_team.rst (100%)

diff --git a/_build/redirection_map b/_build/redirection_map
index 4fb14724d26..3bad633e0e1 100644
--- a/_build/redirection_map
+++ b/_build/redirection_map
@@ -430,6 +430,7 @@
 /email/spool /mailer
 /email/testing /mailer
 /contributing/community/other /contributing/community
+/contributing/code/core_team /contributing/core_team
 /profiler/storage /profiler
 /setup/composer /setup
 /security/security_checker /setup
diff --git a/_images/sources/README.md b/_images/sources/README.md
index 467d4024010..84810a9783d 100644
--- a/_images/sources/README.md
+++ b/_images/sources/README.md
@@ -96,7 +96,7 @@ only the asciicast file).
 
 [1]: http://dia-installer.de/
 [2]: https://fonts.google.com/specimen/PT+Sans+Narrow
-[3]: https://symfony.com/doc/current/contributing/code/core_team.html
+[3]: https://symfony.com/doc/current/contributing/core_team.html
 [4]: https://github.com/asciinema/asciinema
 [5]: https://github.com/asciinema/agg
 [6]: https://www.jetbrains.com/lp/mono/
diff --git a/contributing/code/index.rst b/contributing/code/index.rst
index e537eb3a0c3..b4cf85441b0 100644
--- a/contributing/code/index.rst
+++ b/contributing/code/index.rst
@@ -9,7 +9,6 @@ Contributing Code
     reproducer
     pull_requests
     maintenance
-    core_team
     security
     tests
     bc
diff --git a/contributing/code/pull_requests.rst b/contributing/code/pull_requests.rst
index 7b51b2ab3cb..548fc6c190c 100644
--- a/contributing/code/pull_requests.rst
+++ b/contributing/code/pull_requests.rst
@@ -404,7 +404,7 @@ perspective, please join the ``#contribs`` channel on `Symfony Slack`_. If you
 receive feedback you find abusive please contact the
 :doc:`CARE team </contributing/code_of_conduct/care_team>`.
 
-The :doc:`core team </contributing/code/core_team>` is responsible for deciding
+The :doc:`core team </contributing/core_team>` is responsible for deciding
 which PR gets merged, so their feedback is the most relevant. So do not feel
 pressured to refactor your code immediately when someone provides feedback.
 
diff --git a/contributing/code/standards.rst b/contributing/code/standards.rst
index ced2568c5f7..3a00343faf1 100644
--- a/contributing/code/standards.rst
+++ b/contributing/code/standards.rst
@@ -300,7 +300,7 @@ Documentation
 * When adding a new class or when making significant changes to an existing class,
   an ``@author`` tag with personal contact information may be added, or expanded.
   Please note it is possible to have the personal contact information updated or
-  removed per request to the :doc:`core team </contributing/code/core_team>`.
+  removed per request to the :doc:`core team </contributing/core_team>`.
 
 License
 ~~~~~~~
diff --git a/contributing/code_of_conduct/care_team.rst b/contributing/code_of_conduct/care_team.rst
index e061c0a0afe..1b15850da39 100644
--- a/contributing/code_of_conduct/care_team.rst
+++ b/contributing/code_of_conduct/care_team.rst
@@ -54,7 +54,7 @@ also contact all of them at once by emailing ** care@symfony.com **.
 About the CARE Team
 -------------------
 
-The :doc:`Symfony project leader </contributing/code/core_team>` appoints the CARE
+The :doc:`Symfony project leader </contributing/core_team>` appoints the CARE
 team with candidates they see fit. The CARE team will consist of at least
 3 people. The team should be representing as many demographics as possible,
 ideally from different employers.
diff --git a/contributing/community/releases.rst b/contributing/community/releases.rst
index 8126496bfef..2c5a796e9b5 100644
--- a/contributing/community/releases.rst
+++ b/contributing/community/releases.rst
@@ -113,7 +113,7 @@ PHP Compatibility
 -----------------
 
 The **minimum** PHP version is decided for each **major** Symfony version by consensus
-amongst the :doc:`core team </contributing/code/core_team>` and documented as
+amongst the :doc:`core team </contributing/core_team>` and documented as
 part of the :ref:`technical requirements for running Symfony applications
 <symfony-tech-requirements>`.
 
diff --git a/contributing/code/core_team.rst b/contributing/core_team.rst
similarity index 100%
rename from contributing/code/core_team.rst
rename to contributing/core_team.rst
diff --git a/contributing/map.rst.inc b/contributing/map.rst.inc
index 92bc1e2e142..acbb24bb9b0 100644
--- a/contributing/map.rst.inc
+++ b/contributing/map.rst.inc
@@ -1,3 +1,5 @@
+* :doc:`The Core Team </contributing/core_team>`
+
 * **Code of Conduct**
 
   * :doc:`/contributing/code_of_conduct/code_of_conduct`
@@ -12,7 +14,6 @@
   * :doc:`Pull Requests </contributing/code/pull_requests>`
   * :doc:`Reviewing Issues and Pull Requests </contributing/community/reviews>`
   * :doc:`Maintenance </contributing/code/maintenance>`
-  * :doc:`The Core Team </contributing/code/core_team>`
   * :doc:`Security </contributing/code/security>`
   * :doc:`Tests </contributing/code/tests>`
   * :doc:`Backward Compatibility </contributing/code/bc>`

From 0d296fc0f69cf15d0195000cbe0a904fabb1e08a Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 24 Feb 2025 16:29:52 +0100
Subject: [PATCH 529/747] Minor tweak

---
 messenger.rst | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index 477ef65b740..de72419aa9c 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2065,10 +2065,10 @@ The transport has a number of options:
     Name of the queue
 
 ``queue_attributes``
-    Attributes of a queue as per `SQS CreateQueue API`_. Array of strings indexed by keys of ``AsyncAws\Sqs\Enum\QueueAttributeName``. Added in Symfony 7.3.
+    Attributes of a queue as per `SQS CreateQueue API`_. Array of strings indexed by keys of ``AsyncAws\Sqs\Enum\QueueAttributeName``.
 
 ``queue_tags``
-    Cost allocation tags of a queue as per `SQS CreateQueue API`_. Array of strings indexed by strings. Added in Symfony 7.3.
+    Cost allocation tags of a queue as per `SQS CreateQueue API`_. Array of strings indexed by strings.
 
 ``region`` (default: ``eu-west-1``)
     Name of the AWS region
@@ -2085,6 +2085,10 @@ The transport has a number of options:
 ``wait_time`` (default: ``20``)
     `Long polling`_ duration in seconds
 
+.. versionadded:: 7.3
+
+    The ``queue_attributes`` and ``queue_tags`` options were introduced in Symfony 7.3.
+
 .. note::
 
     The ``wait_time`` parameter defines the maximum duration Amazon SQS should

From a2daec4d72e47b9ce07e0bc915834f3594b7f453 Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Wed, 26 Feb 2025 12:18:13 +0100
Subject: [PATCH 530/747] [Config] Allow using an enum FQCN with `EnumNode`

---
 components/config/definition.rst | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/components/config/definition.rst b/components/config/definition.rst
index 24c142ec5a5..b22d66c2b51 100644
--- a/components/config/definition.rst
+++ b/components/config/definition.rst
@@ -186,6 +186,25 @@ The configuration can now be written like this::
         ->end()
     ;
 
+You can also use the ``enumClass()`` method to pass the FQCN of an enum
+class to the node. This will automatically set the values of the node to
+the cases of the enum::
+
+    $rootNode
+        ->children()
+            ->enumNode('delivery')
+                ->enumClass(Delivery::class)
+            ->end()
+        ->end()
+    ;
+
+When using a backed enum, the values provided to the node will be casted
+to one of the enum cases if possible.
+
+.. versionadded:: 7.3
+
+    The ``enumClass()`` method was introduced in Symfony 7.3.
+
 Array Nodes
 ~~~~~~~~~~~
 

From f0be895bcf93a85fba888e476d0e580483b98f89 Mon Sep 17 00:00:00 2001
From: Florent Morselli <florent.morselli@spomky-labs.com>
Date: Wed, 26 Feb 2025 17:13:11 +0100
Subject: [PATCH 531/747] [Mailer] [Amazon] Remove outdated warning

As per https://github.com/symfony/symfony/pull/58761, the warning about requiring the `ses+https` provider for custom headers is no longer relevant and has been removed.
Fixes https://github.com/symfony/symfony-docs/issues/20512
---
 mailer.rst | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index 9ab2f47c235..fd34a921b14 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -268,12 +268,6 @@ party provider:
     you need to add the ``ping_threshold`` parameter to your ``MAILER_DSN`` with
     a value lower than ``10``: ``ses+smtp://USERNAME:PASSWORD@default?ping_threshold=9``
 
-.. warning::
-
-    If you send custom headers when using the `Amazon SES`_ transport (to receive
-    them later via a webhook), make sure to use the ``ses+https`` provider because
-    it's the only one that supports them.
-
 .. note::
 
     When using SMTP, the default timeout for sending a message before throwing an

From 63fc4e0fbe5bf2f1c2d6535c8a5a5f6a469f2c93 Mon Sep 17 00:00:00 2001
From: Florent Morselli <florent.morselli@spomky-labs.com>
Date: Wed, 26 Feb 2025 21:51:36 +0100
Subject: [PATCH 532/747] [Messenger] Priority support for Beanstalkd bridge

Adds explanation about the new `BeanstalkdPriorityStamp` introduced by https://github.com/symfony/symfony/pull/59273
Fixes https://github.com/symfony/symfony-docs/issues/20513
---
 messenger.rst | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index de72419aa9c..a9270ae1673 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1789,6 +1789,29 @@ The transport has a number of options:
 
     Keepalive support, using the ``--keepalive`` option, was added in Symfony 7.2.
 
+When using the Beanstalkd transport in Symfony Messenger, you can now set the priority of the messages being dispatched.
+This allows you to control the order in which the messages are processed, with lower values indicating higher priority.
+
+To configure the priority, use the ``Symfony\Component\Messenger\Bridge\Beanstalkd\Transport\BeanstalkdPriorityStamp``
+when dispatching a message:
+
+.. code-block:: php
+
+    use App\Message\SomeMessage;
+    use Symfony\Component\Messenger\Stamp\BeanstalkdPriorityStamp;
+
+    $this->bus->dispatch(new SomeMessage('some data'), [
+        new BeanstalkdPriorityStamp(0), // Highest priority
+    ]);
+
+As defined by the Beanstalkd protocol, the priority value must be an integer between 0 (highest priority) and 2**32 (lowest priority).
+
+If no priority is specified, the default value ``1024`` will be used.
+
+.. versionadded:: 7.3
+
+    ``BeanstalkdPriorityStamp`` support was added in Symfony 7.3.
+
 .. _messenger-redis-transport:
 
 Redis Transport

From e9c4f9079e08c2f3a4e5c56b2a1a5902a1950bc5 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@open.de>
Date: Thu, 27 Feb 2025 09:05:50 +0100
Subject: [PATCH 533/747] fix typo

---
 components/config/definition.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/config/definition.rst b/components/config/definition.rst
index b22d66c2b51..44189d9dd6f 100644
--- a/components/config/definition.rst
+++ b/components/config/definition.rst
@@ -198,7 +198,7 @@ the cases of the enum::
         ->end()
     ;
 
-When using a backed enum, the values provided to the node will be casted
+When using a backed enum, the values provided to the node will be cast
 to one of the enum cases if possible.
 
 .. versionadded:: 7.3

From 04f5498101f6cc4166bbdbfd29c583b6137840c5 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 27 Feb 2025 12:44:55 +0100
Subject: [PATCH 534/747] Reword

---
 messenger.rst | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index a9270ae1673..3618482f8e9 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1789,28 +1789,22 @@ The transport has a number of options:
 
     Keepalive support, using the ``--keepalive`` option, was added in Symfony 7.2.
 
-When using the Beanstalkd transport in Symfony Messenger, you can now set the priority of the messages being dispatched.
-This allows you to control the order in which the messages are processed, with lower values indicating higher priority.
-
-To configure the priority, use the ``Symfony\Component\Messenger\Bridge\Beanstalkd\Transport\BeanstalkdPriorityStamp``
-when dispatching a message:
-
-.. code-block:: php
+The Beanstalkd transport lets you set the priority of the messages being dispatched.
+Use the ``Symfony\Component\Messenger\Bridge\Beanstalkd\Transport\BeanstalkdPriorityStamp``
+and pass a number to specify the priority (default = ``1024``; lower numbers mean higher priority)::
 
     use App\Message\SomeMessage;
     use Symfony\Component\Messenger\Stamp\BeanstalkdPriorityStamp;
 
     $this->bus->dispatch(new SomeMessage('some data'), [
-        new BeanstalkdPriorityStamp(0), // Highest priority
+        // 0 = highest priority
+        // 2**32 - 1 = lowest priority
+        new BeanstalkdPriorityStamp(0),
     ]);
 
-As defined by the Beanstalkd protocol, the priority value must be an integer between 0 (highest priority) and 2**32 (lowest priority).
-
-If no priority is specified, the default value ``1024`` will be used.
-
 .. versionadded:: 7.3
 
-    ``BeanstalkdPriorityStamp`` support was added in Symfony 7.3.
+    ``BeanstalkdPriorityStamp`` support was introduced in Symfony 7.3.
 
 .. _messenger-redis-transport:
 

From d976d0e8e24fa97520b1fb513027ee723dd05893 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lo=C3=AFck=20Piera?= <pyrech@gmail.com>
Date: Sat, 1 Mar 2025 17:56:22 +0100
Subject: [PATCH 535/747] Add documentation for error:dump command

---
 controller/error_pages.rst | 46 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/controller/error_pages.rst b/controller/error_pages.rst
index fc36b88779a..00a36f3b13a 100644
--- a/controller/error_pages.rst
+++ b/controller/error_pages.rst
@@ -336,3 +336,49 @@ time and again, you can have just one (or several) listeners deal with them.
     your application (like :class:`Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException`)
     and takes measures like redirecting the user to the login page, logging them
     out and other things.
+
+Dumping error pages in static HTML files
+----------------------------------------
+
+When a web server cannot handle a request or when it triggers an error without
+calling the PHP application, it will return its default error pages, instead of
+rendering the errors as defined in your application (whether it's Symfony's
+default "Oops" error page or the pages you customized in your application).
+
+To avoid that and always have your web server rendering your application's error
+pages, you can dump each HTTP status error in a their own static HTML files:
+
+.. code-block:: terminal
+
+    $ php bin/console error:dump [--force] var/cache/prod/error_pages
+
+.. note::
+
+    By default, it will dump HTML files for each HTTP status error.
+    You can restrict that to dump only some HTTP status code by passing them as
+    in the second argument of the command.
+
+Once the static pages are generated, you can now configure your web server to use
+them instead of their default error page. Here is an example configuration with
+nginx:
+
+.. code-block:: nginx
+
+    # /etc/nginx/conf.d/example.com.conf
+    server {
+        # Your existing serverconfiguration
+        # ...
+
+
+	# Configure nginx to serve your application's error pages
+        error_page 400 /error_pages/400.html;
+        error_page 401 /error_pages/401.html;
+        # ...
+        error_page 510 /error_pages/510.html;
+        error_page 511 /error_pages/511.html;
+
+        location ^~ /error_pages/ {
+          root /path/to/your/symfony/var/cache/error_pages;
+          internal; # allows this location block to not be triggered when a user manually call these /error_pages/.* urls
+        }
+    }

From 3c3b2ea33bcf2162a89182951b209be09d18b97d Mon Sep 17 00:00:00 2001
From: Alan Poulain <contact@alanpoulain.eu>
Date: Sat, 1 Mar 2025 19:53:16 +0100
Subject: [PATCH 536/747] [Serializer] Add defaultType to DiscriminatorMap

---
 serializer.rst | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/serializer.rst b/serializer.rst
index d541310aa15..23be4a234a8 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -2033,6 +2033,70 @@ correct class for properties typed as ``InvoiceItemInterface``::
         $invoiceLine = $serializer->deserialize($jsonString, InvoiceLine::class, 'json');
         // $invoiceLine contains new InvoiceLine(new Product(...))
 
+You can add a default type to avoid the need to add the type property
+when deserializing:
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        namespace App\Model;
+
+        use Symfony\Component\Serializer\Attribute\DiscriminatorMap;
+
+        #[DiscriminatorMap(
+            typeProperty: 'type',
+            mapping: [
+                'product' => Product::class,
+                'shipping' => Shipping::class,
+            ],
+            defaultType: 'product',
+        )]
+        interface InvoiceItemInterface
+        {
+            // ...
+        }
+
+    .. code-block:: yaml
+
+        App\Model\InvoiceItemInterface:
+            discriminator_map:
+                type_property: type
+                mapping:
+                    product: 'App\Model\Product'
+                    shipping: 'App\Model\Shipping'
+                default_type: product
+
+    .. code-block:: xml
+
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
+                https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
+        >
+            <class name="App\Model\InvoiceItemInterface">
+                <discriminator-map type-property="type" default-type="product">
+                    <mapping type="product" class="App\Model\Product"/>
+                    <mapping type="shipping" class="App\Model\Shipping"/>
+                </discriminator-map>
+            </class>
+        </serializer>
+
+Now it deserializes like this:
+
+.. configuration-block::
+
+    .. code-block:: php
+
+        // $jsonString does NOT contain "type" in "invoiceItem"
+        $invoiceLine = $serializer->deserialize('{"invoiceItem":{...},...}', InvoiceLine::class, 'json');
+        // $invoiceLine contains new InvoiceLine(new Product(...))
+
+.. versionadded:: 7.3
+
+    The ``defaultType`` parameter was added in Symfony 7.3.
+
 .. _serializer-unwrapping-denormalizer:
 
 Deserializing Input Partially (Unwrapping)

From 569f548afe86539b48925fed3e1ba68fe6c3c0e9 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 4 Mar 2025 08:28:55 +0100
Subject: [PATCH 537/747] [Reference] Sort debug options alphabetically

---
 reference/configuration/debug.rst | 52 +++++++++++++++----------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/reference/configuration/debug.rst b/reference/configuration/debug.rst
index cd42d79d157..6ca05b49bd7 100644
--- a/reference/configuration/debug.rst
+++ b/reference/configuration/debug.rst
@@ -23,32 +23,6 @@ key in your application configuration.
     namespace and the related XSD schema is available at:
     ``https://symfony.com/schema/dic/debug/debug-1.0.xsd``
 
-max_items
-~~~~~~~~~
-
-**type**: ``integer`` **default**: ``2500``
-
-This is the maximum number of items to dump. Setting this option to ``-1``
-disables the limit.
-
-min_depth
-~~~~~~~~~
-
-**type**: ``integer`` **default**: ``1``
-
-Configures the minimum tree depth until which all items are guaranteed to
-be cloned. After this depth is reached, only ``max_items`` items will be
-cloned. The default value is ``1``, which is consistent with older Symfony
-versions.
-
-max_string_length
-~~~~~~~~~~~~~~~~~
-
-**type**: ``integer`` **default**: ``-1``
-
-This option configures the maximum string length before truncating the
-string. The default value (``-1``) means that strings are never truncated.
-
 .. _configuration-debug-dump_destination:
 
 dump_destination
@@ -98,3 +72,29 @@ Typically, you would set this to ``php://stderr``:
 
 
 Configure it to ``"tcp://%env(VAR_DUMPER_SERVER)%"`` in order to use the :ref:`ServerDumper feature <var-dumper-dump-server>`.
+
+max_items
+~~~~~~~~~
+
+**type**: ``integer`` **default**: ``2500``
+
+This is the maximum number of items to dump. Setting this option to ``-1``
+disables the limit.
+
+max_string_length
+~~~~~~~~~~~~~~~~~
+
+**type**: ``integer`` **default**: ``-1``
+
+This option configures the maximum string length before truncating the
+string. The default value (``-1``) means that strings are never truncated.
+
+min_depth
+~~~~~~~~~
+
+**type**: ``integer`` **default**: ``1``
+
+Configures the minimum tree depth until which all items are guaranteed to
+be cloned. After this depth is reached, only ``max_items`` items will be
+cloned. The default value is ``1``, which is consistent with older Symfony
+versions.

From 96bb798bc1dce7780827dd51cecaafde94b9ae6c Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 4 Mar 2025 09:40:01 +0100
Subject: [PATCH 538/747] [Reference] Sort all framework options alphabetically

---
 reference/configuration/framework.rst | 4643 +++++++++++++------------
 1 file changed, 2322 insertions(+), 2321 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index e58a7ebc80f..0334b918c66 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -19,236 +19,355 @@ configured under the ``framework`` key in your application configuration.
     namespace and the related XSD schema is available at:
     ``https://symfony.com/schema/dic/symfony/symfony-1.0.xsd``
 
-.. _configuration-framework-secret:
+annotations
+~~~~~~~~~~~
 
-secret
-~~~~~~
+.. _reference-annotations-cache:
 
-**type**: ``string`` **required**
+cache
+.....
 
-This is a string that should be unique to your application and it's commonly
-used to add more entropy to security related operations. Its value should
-be a series of characters, numbers and symbols chosen randomly and the
-recommended length is around 32 characters.
+**type**: ``string`` **default**: ``php_array``
 
-In practice, Symfony uses this value for encrypting the cookies used
-in the :doc:`remember me functionality </security/remember_me>` and for
-creating signed URIs when using :ref:`ESI (Edge Side Includes) <edge-side-includes>`.
-That's why you should treat this value as if it were a sensitive credential and
-**never make it public**.
+This option can be one of the following values:
 
-This option becomes the service container parameter named ``kernel.secret``,
-which you can use whenever the application needs an immutable random string
-to add more entropy.
+php_array
+    Use a PHP array to cache annotations in memory
+file
+    Use the filesystem to cache annotations
+none
+    Disable the caching of annotations
 
-As with any other security-related parameter, it is a good practice to change
-this value from time to time. However, keep in mind that changing this value
-will invalidate all signed URIs and Remember Me cookies. That's why, after
-changing this value, you should regenerate the application cache and log
-out all the application users.
+debug
+.....
 
-handle_all_throwables
-~~~~~~~~~~~~~~~~~~~~~
+**type**: ``boolean`` **default**: ``%kernel.debug%``
 
-**type**: ``boolean`` **default**: ``true``
+Whether to enable debug mode for caching. If enabled, the cache will
+automatically update when the original file is changed (both with code and
+annotation changes). For performance reasons, it is recommended to disable
+debug mode in production, which will happen automatically if you use the
+default value.
 
-When set to ``true``, the Symfony kernel will catch all ``\Throwable`` exceptions
-thrown by the application and will turn them into HTTP responses.
+file_cache_dir
+..............
 
-.. _configuration-framework-http_cache:
+**type**: ``string`` **default**: ``%kernel.cache_dir%/annotations``
 
-http_cache
-~~~~~~~~~~
+The directory to store cache files for annotations, in case
+``annotations.cache`` is set to ``'file'``.
 
-enabled
-.......
+assets
+~~~~~~
 
-**type**: ``boolean`` **default**: ``false``
+.. _reference-assets-base-path:
 
-debug
-.....
+base_path
+.........
 
-**type**: ``boolean`` **default**: ``%kernel.debug%``
+**type**: ``string``
 
-If true, exceptions are thrown when things go wrong. Otherwise, the cache will
-try to carry on and deliver a meaningful response.
+This option allows you to define a base path to be used for assets:
 
-trace_level
-...........
+.. configuration-block::
 
-**type**: ``string`` **possible values**: ``'none'``, ``'short'`` or ``'full'``
+    .. code-block:: yaml
 
-For 'short', a concise trace of the main request will be added as an HTTP header.
-'full' will add traces for all requests (including ESI subrequests).
-(default: 'full' if in debug; 'none' otherwise)
+        # config/packages/framework.yaml
+        framework:
+            # ...
+            assets:
+                base_path: '/images'
 
-trace_header
-............
+    .. code-block:: xml
 
-**type**: ``string``
+        <!-- config/packages/framework.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
-Header name to use for traces. (default: X-Symfony-Cache)
+            <framework:config>
+                <framework:assets base-path="/images"/>
+            </framework:config>
+        </container>
 
-default_ttl
-...........
+    .. code-block:: php
 
-**type**: ``integer``
+        // config/packages/framework.php
+        use Symfony\Config\FrameworkConfig;
 
-The number of seconds that a cache entry should be considered fresh when no
-explicit freshness information is provided in a response. Explicit
-Cache-Control or Expires headers override this value. (default: 0)
+        return static function (FrameworkConfig $framework): void {
+            // ...
+            $framework->assets()
+                ->basePath('/images');
+        };
 
-private_headers
-...............
+.. _reference-templating-base-urls:
+.. _reference-assets-base-urls:
+
+base_urls
+.........
 
 **type**: ``array``
 
-Set of request headers that trigger "private" cache-control behavior on responses
-that don't explicitly state whether the response is public or private via a
-Cache-Control directive. (default: Authorization and Cookie)
+This option allows you to define base URLs to be used for assets.
+If multiple base URLs are provided, Symfony will select one from the
+collection each time it generates an asset's path:
 
-skip_response_headers
-.....................
+.. configuration-block::
 
-**type**: ``array`` **default**: ``Set-Cookie``
+    .. code-block:: yaml
 
-Set of response headers that will never be cached even when the response is cacheable
-and public.
+        # config/packages/framework.yaml
+        framework:
+            # ...
+            assets:
+                base_urls:
+                    - 'http://cdn.example.com/'
 
-allow_reload
-............
+    .. code-block:: xml
 
-**type**: ``string``
+        <!-- config/packages/framework.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
-Specifies whether the client can force a cache reload by including a
-Cache-Control "no-cache" directive in the request. Set it to ``true``
-for compliance with RFC 2616. (default: false)
+            <framework:config>
+                <framework:assets base-url="http://cdn.example.com/"/>
+            </framework:config>
+        </container>
 
-allow_revalidate
-................
+    .. code-block:: php
 
-**type**: ``string``
+        // config/packages/framework.php
+        use Symfony\Config\FrameworkConfig;
 
-Specifies whether the client can force a cache revalidate by including a
-Cache-Control "max-age=0" directive in the request. Set it to ``true``
-for compliance with RFC 2616. (default: false)
+        return static function (FrameworkConfig $framework): void {
+            // ...
+            $framework->assets()
+                ->baseUrls(['http://cdn.example.com/']);
+        };
 
-stale_while_revalidate
-......................
+.. _reference-assets-json-manifest-path:
+.. _reference-templating-json-manifest-path:
 
-**type**: ``integer``
+json_manifest_path
+..................
 
-Specifies the default number of seconds (the granularity is the second as the
-Response TTL precision is a second) during which the cache can immediately return
-a stale response while it revalidates it in the background (default: 2).
-This setting is overridden by the stale-while-revalidate HTTP Cache-Control
-extension (see RFC 5861).
+**type**: ``string`` **default**: ``null``
 
-stale_if_error
-..............
+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.
 
-**type**: ``integer``
+.. tip::
 
-Specifies the default number of seconds (the granularity is the second) during
-which the cache can serve a stale response when an error is encountered
-(default: 60). This setting is overridden by the stale-if-error HTTP
-Cache-Control extension (see RFC 5861).
+    Symfony's :ref:`Webpack Encore <frontend-webpack-encore>` supports
+    :ref:`outputting hashed assets <encore-long-term-caching>`. Moreover, this
+    can be incorporated into many other workflows, including Webpack and
+    Gulp using `webpack-manifest-plugin`_ and `gulp-rev`_, respectively.
+
+This option can be set globally for all assets and individually for each asset
+package:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/framework.yaml
+        framework:
+            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)
+                        json_manifest_path: "%kernel.project_dir%/public/build/a_different_manifest.json"
+                        # Throws an exception when an asset is not found in the manifest
+                        strict_mode: %kernel.debug%
+                    bar_package:
+                        # this package uses the global manifest (the default file is used)
+                        base_path: '/images'
+
+    .. code-block:: xml
+
+        <!-- config/packages/framework.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <framework:config>
+                <!-- this manifest is applied to every asset (including packages) -->
+                <framework:assets json-manifest-path="%kernel.project_dir%/public/build/manifest.json">
+                <!-- you can use absolute URLs too and Symfony will download them automatically -->
+                <!-- <framework:assets json-manifest-path="https://cdn.example.com/manifest.json"> -->
+                    <!-- this package uses its own manifest (the default file is ignored) -->
+                    <!-- Throws an exception when an asset is not found in the manifest -->
+                    <framework:package
+                        name="foo_package"
+                        json-manifest-path="%kernel.project_dir%/public/build/a_different_manifest.json" strict-mode="%kernel.debug%"/>
+                    <!-- this package uses the global manifest (the default file is used) -->
+                    <framework:package
+                        name="bar_package"
+                        base-path="/images"/>
+                </framework:assets>
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/framework.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            // ...
+            $framework->assets()
+                // this manifest is applied to every asset (including packages)
+                ->jsonManifestPath('%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',
+            $framework->assets()->package('foo_package')
+                // this package uses its own manifest (the default file is ignored)
+                ->jsonManifestPath('%kernel.project_dir%/public/build/a_different_manifest.json')
+                // Throws an exception when an asset is not found in the manifest
+                ->setStrictMode('%kernel.debug%');
+
+            $framework->assets()->package('bar_package')
+                // this package uses the global manifest (the default file is used)
+                ->basePath('/images');
+        };
+
+.. note::
+
+    This parameter cannot be set at the same time as ``version`` or ``version_strategy``.
+    Additionally, this option cannot be nullified at the package scope if a global manifest
+    file is specified.
+
+.. tip::
+
+    If you request an asset that is *not found* in the ``manifest.json`` file, the original -
+    *unmodified* - asset path will be returned.
+    You can set ``strict_mode`` to ``true`` to get an exception when an asset is *not found*.
 
- .. _configuration-framework-http_method_override:
+.. note::
 
-http_method_override
-~~~~~~~~~~~~~~~~~~~~
+    If a URL is set, the JSON manifest is downloaded on each request using the `http_client`_.
 
-**type**: ``boolean`` **default**: ``false``
+.. _reference-framework-assets-packages:
 
-This determines whether the ``_method`` request parameter is used as the
-intended HTTP method on POST requests. If enabled, the
-:method:`Request::enableHttpMethodParameterOverride <Symfony\\Component\\HttpFoundation\\Request::enableHttpMethodParameterOverride>`
-method gets called automatically. It becomes the service container parameter
-named ``kernel.http_method_override``.
+packages
+........
 
-.. seealso::
+You can group assets into packages, to specify different base URLs for them:
 
-    :ref:`Changing the Action and HTTP Method <forms-change-action-method>` of
-    Symfony forms.
+.. configuration-block::
 
-.. warning::
+    .. code-block:: yaml
 
-    If you're using the :ref:`HttpCache Reverse Proxy <symfony2-reverse-proxy>`
-    with this option, the kernel will ignore the ``_method`` parameter,
-    which could lead to errors.
+        # config/packages/framework.yaml
+        framework:
+            # ...
+            assets:
+                packages:
+                    avatars:
+                        base_urls: 'http://static_cdn.example.com/avatars'
 
-    To fix this, invoke the ``enableHttpMethodParameterOverride()`` method
-    before creating the ``Request`` object::
+    .. code-block:: xml
 
-        // public/index.php
+        <!-- config/packages/framework.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
-        // ...
-        $kernel = new CacheKernel($kernel);
+            <framework:config>
+                <framework:assets>
+                    <framework:package
+                        name="avatars"
+                        base-url="http://static_cdn.example.com/avatars"/>
+                </framework:assets>
+            </framework:config>
+        </container>
 
-        Request::enableHttpMethodParameterOverride(); // <-- add this line
-        $request = Request::createFromGlobals();
-        // ...
+    .. code-block:: php
 
-trust_x_sendfile_type_header
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        // config/packages/framework.php
+        use Symfony\Config\FrameworkConfig;
 
-**type**: ``boolean`` **default**: ``%env(bool:default::SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER)%``
+        return static function (FrameworkConfig $framework): void {
+            // ...
+            $framework->assets()
+                ->package('avatars')
+                    ->baseUrls(['http://static_cdn.example.com/avatars']);
+        };
 
-.. versionadded:: 7.2
+Now you can use the ``avatars`` package in your templates:
 
-    In Symfony 7.2, the default value of this option was changed from ``false`` to the
-    value stored in the ``SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER`` environment variable.
+.. code-block:: html+twig
 
-``X-Sendfile`` is a special HTTP header that tells web servers to replace the
-response contents by the file that is defined in that header. This improves
-performance because files are no longer served by your application but directly
-by the web server.
+    <img src="{{ asset('...', 'avatars') }}">
 
-This configuration option determines whether to trust ``x-sendfile`` header for
-BinaryFileResponse. If enabled, Symfony calls the
-:method:`BinaryFileResponse::trustXSendfileTypeHeader <Symfony\\Component\\HttpFoundation\\BinaryFileResponse::trustXSendfileTypeHeader>`
-method automatically. It becomes the service container parameter named
-``kernel.trust_x_sendfile_type_header``.
+Each package can configure the following options:
 
-.. _reference-framework-trusted-headers:
+* :ref:`base_path <reference-assets-base-path>`
+* :ref:`base_urls <reference-assets-base-urls>`
+* :ref:`version_strategy <reference-assets-version-strategy>`
+* :ref:`version <reference-framework-assets-version>`
+* :ref:`version_format <reference-assets-version-format>`
+* :ref:`json_manifest_path <reference-assets-json-manifest-path>`
+* :ref:`strict_mode <reference-assets-strict-mode>`
 
-trusted_headers
-~~~~~~~~~~~~~~~
+.. _reference-assets-strict-mode:
 
-The ``trusted_headers`` option is needed to configure which client information
-should be trusted (e.g. their host) when running Symfony behind a load balancer
-or a reverse proxy. See :doc:`/deployment/proxies`.
+strict_mode
+...........
 
-.. _reference-framework-trusted-proxies:
+**type**: ``boolean`` **default**: ``false``
 
-trusted_proxies
-~~~~~~~~~~~~~~~
+When enabled, the strict mode asserts that all requested assets are in the
+manifest file. This option is useful to detect typos or missing assets, the
+recommended value is ``%kernel.debug%``.
 
-The ``trusted_proxies`` option is needed to get precise information about the
-client (e.g. their IP address) when running Symfony behind a load balancer or a
-reverse proxy. See :doc:`/deployment/proxies`.
+.. _reference-framework-assets-version:
+.. _ref-framework-assets-version:
 
-ide
-~~~
+version
+.......
 
-**type**: ``string`` **default**: ``%env(default::SYMFONY_IDE)%``
+**type**: ``string``
 
-Symfony turns file paths seen in variable dumps and exception messages into
-links that open those files right inside your browser. If you prefer to open
-those files in your favorite IDE or text editor, set this option to any of the
-following values: ``phpstorm``, ``sublime``, ``textmate``, ``macvim``, ``emacs``,
-``atom`` and ``vscode``.
+This option is used to *bust* the cache on assets by globally adding a query
+parameter to all rendered asset paths (e.g. ``/images/logo.png?v2``). This
+applies only to assets rendered via the Twig ``asset()`` function (or PHP
+equivalent).
 
-.. note::
+For example, suppose you have the following:
 
-    The ``phpstorm`` option is supported natively by PhpStorm on macOS and
-    Windows; Linux requires installing `phpstorm-url-handler`_.
+.. code-block:: html+twig
 
-If you use another editor, the expected configuration value is a URL template
-that contains an ``%f`` placeholder where the file path is expected and ``%l``
-placeholder for the line number (percentage signs (``%``) must be escaped by
-doubling them to prevent Symfony from interpreting them as container parameters).
+    <img src="{{ asset('images/logo.png') }}" alt="Symfony!"/>
+
+By default, this will render a path to your image such as ``/images/logo.png``.
+Now, activate the ``version`` option:
 
 .. configuration-block::
 
@@ -256,7 +375,9 @@ doubling them to prevent Symfony from interpreting them as container parameters)
 
         # config/packages/framework.yaml
         framework:
-            ide: 'myide://open?url=file://%%f&line=%%l'
+            # ...
+            assets:
+                version: 'v2'
 
     .. code-block:: xml
 
@@ -269,7 +390,9 @@ doubling them to prevent Symfony from interpreting them as container parameters)
                 https://symfony.com/schema/dic/services/services-1.0.xsd
                 http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
-            <framework:config ide="myide://open?url=file://%%f&line=%%l"/>
+            <framework:config>
+                <framework:assets version="v2"/>
+            </framework:config>
         </container>
 
     .. code-block:: php
@@ -278,203 +401,245 @@ doubling them to prevent Symfony from interpreting them as container parameters)
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
-            $framework->ide('myide://open?url=file://%%f&line=%%l');
+            // ...
+            $framework->assets()
+                ->version('v2');
         };
 
-Since every developer uses a different IDE, the recommended way to enable this
-feature is to configure it on a system level. First, you can define this option
-in the ``SYMFONY_IDE`` environment variable, which Symfony reads automatically
-when ``framework.ide`` config is not set.
-
-Another alternative is to set the ``xdebug.file_link_format`` option in your
-``php.ini`` configuration file. The format to use is the same as for the
-``framework.ide`` option, but without the need to escape the percent signs
-(``%``) by doubling them:
-
-.. code-block:: ini
-
-    // example for PhpStorm
-    xdebug.file_link_format="phpstorm://open?file=%f&line=%l"
-
-    // example for PhpStorm with Jetbrains Toolbox
-    xdebug.file_link_format="jetbrains://phpstorm/navigate/reference?project=example&path=%f:%l"
+Now, the same asset will be rendered as ``/images/logo.png?v2`` If you use
+this feature, you **must** manually increment the ``version`` value
+before each deployment so that the query parameters change.
 
-    // example for Sublime Text
-    xdebug.file_link_format="subl://open?url=file://%f&line=%l"
+You can also control how the query string works via the `version_format`_
+option.
 
 .. note::
 
-    If both ``framework.ide`` and ``xdebug.file_link_format`` are defined,
-    Symfony uses the value of the ``xdebug.file_link_format`` option.
-
-.. tip::
-
-    Setting the ``xdebug.file_link_format`` ini option works even if the Xdebug
-    extension is not enabled.
+    This parameter cannot be set at the same time as ``version_strategy`` or ``json_manifest_path``.
 
 .. tip::
 
-    When running your app in a container or in a virtual machine, you can tell
-    Symfony to map files from the guest to the host by changing their prefix.
-    This map should be specified at the end of the URL template, using ``&`` and
-    ``>`` as guest-to-host separators:
-
-    .. code-block:: text
-
-        // /path/to/guest/.../file will be opened
-        // as /path/to/host/.../file on the host
-        // and /var/www/app/ as /projects/my_project/ also
-        'myide://%%f:%%l&/path/to/guest/>/path/to/host/&/var/www/app/>/projects/my_project/&...'
-
-        // example for PhpStorm
-        'phpstorm://open?file=%%f&line=%%l&/var/www/app/>/projects/my_project/'
-
-.. _reference-framework-test:
-
-test
-~~~~
+    As with all settings, you can use a parameter as value for the
+    ``version``. This makes it easier to increment the cache on each
+    deployment.
 
-**type**: ``boolean``
+.. _reference-templating-version-format:
+.. _reference-assets-version-format:
 
-If this configuration setting is present (and not ``false``), then the services
-related to testing your application (e.g. ``test.client``) are loaded. This
-setting should be present in your ``test`` environment (usually via
-``config/packages/test/framework.yaml``).
+version_format
+..............
 
-.. seealso::
+**type**: ``string`` **default**: ``%%s?%%s``
 
-    For more information, see :doc:`/testing`.
+This specifies a :phpfunction:`sprintf` pattern that will be used with the
+`version`_ option to construct an asset's path. By default, the pattern
+adds the asset's version as a query string. For example, if
+``version_format`` is set to ``%%s?version=%%s`` and ``version``
+is set to ``5``, the asset's path would be ``/images/logo.png?version=5``.
 
-.. _config-framework-default_locale:
+.. note::
 
-default_locale
-~~~~~~~~~~~~~~
+    All percentage signs (``%``) in the format string must be doubled to
+    escape the character. Without escaping, values might inadvertently be
+    interpreted as :ref:`service-container-parameters`.
 
-**type**: ``string`` **default**: ``en``
+.. tip::
 
-The default locale is used if no ``_locale`` routing parameter has been
-set. It is available with the
-:method:`Request::getDefaultLocale <Symfony\\Component\\HttpFoundation\\Request::getDefaultLocale>`
-method.
+    Some CDN's do not support cache-busting via query strings, so injecting
+    the version into the actual file path is necessary. Thankfully,
+    ``version_format`` is not limited to producing versioned query
+    strings.
 
-.. seealso::
+    The pattern receives the asset's original path and version as its first
+    and second parameters, respectively. Since the asset's path is one
+    parameter, you cannot modify it in-place (e.g. ``/images/logo-v5.png``);
+    however, you can prefix the asset's path using a pattern of
+    ``version-%%2$s/%%1$s``, which would result in the path
+    ``version-5/images/logo.png``.
 
-    You can read more information about the default locale in
-    :ref:`translation-default-locale`.
+    URL rewrite rules could then be used to disregard the version prefix
+    before serving the asset. Alternatively, you could copy assets to the
+    appropriate version path as part of your deployment process and forgot
+    any URL rewriting. The latter option is useful if you would like older
+    asset versions to remain accessible at their original URL.
 
-.. _reference-translator-enabled-locales:
-.. _reference-enabled-locales:
+.. _reference-assets-version-strategy:
+.. _reference-templating-version-strategy:
 
-enabled_locales
-...............
+version_strategy
+................
 
-**type**: ``array`` **default**: ``[]`` (empty array = enable all locales)
+**type**: ``string`` **default**: ``null``
 
-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:
+The service id of the :doc:`asset version strategy </frontend/custom_version_strategy>`
+applied to the assets. This option can be set globally for all assets and
+individually for each asset package:
 
 .. configuration-block::
 
     .. code-block:: yaml
 
-        # config/packages/translation.yaml
+        # config/packages/framework.yaml
         framework:
-            enabled_locales: ['en', 'es']
+            assets:
+                # this strategy is applied to every asset (including packages)
+                version_strategy: 'app.asset.my_versioning_strategy'
+                packages:
+                    foo_package:
+                        # this package removes any versioning (its assets won't be versioned)
+                        version: ~
+                    bar_package:
+                        # this package uses its own strategy (the default strategy is ignored)
+                        version_strategy: 'app.asset.another_version_strategy'
+                    baz_package:
+                        # this package inherits the default strategy
+                        base_path: '/images'
 
     .. code-block:: xml
 
-        <!-- config/packages/translation.xml -->
+        <!-- config/packages/framework.xml -->
         <?xml version="1.0" encoding="UTF-8" ?>
         <container xmlns="http://symfony.com/schema/dic/services"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:framework="http://symfony.com/schema/dic/symfony"
-            xsi:schemaLocation="http://symfony.com/schema/dic/services
-                https://symfony.com/schema/dic/services/services-1.0.xsd
+            xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
                 http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
             <framework:config>
-                <enabled-locale>en</enabled-locale>
-                <enabled-locale>es</enabled-locale>
+                <framework:assets version-strategy="app.asset.my_versioning_strategy">
+                    <!-- this package removes any versioning (its assets won't be versioned) -->
+                    <framework:package
+                        name="foo_package"
+                        version="null"/>
+                    <!-- this package uses its own strategy (the default strategy is ignored) -->
+                    <framework:package
+                        name="bar_package"
+                        version-strategy="app.asset.another_version_strategy"/>
+                    <!-- this package inherits the default strategy -->
+                    <framework:package
+                        name="baz_package"
+                        base_path="/images"/>
+                </framework:assets>
             </framework:config>
         </container>
 
     .. code-block:: php
 
-        // config/packages/translation.php
+        // config/packages/framework.php
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
-            $framework->enabledLocales(['en', 'es']);
+            // ...
+            $framework->assets()
+                ->versionStrategy('app.asset.my_versioning_strategy');
+
+            $framework->assets()->package('foo_package')
+                // this package removes any versioning (its assets won't be versioned)
+                ->version(null);
+
+            $framework->assets()->package('bar_package')
+                // this package uses its own strategy (the default strategy is ignored)
+                ->versionStrategy('app.asset.another_version_strategy');
+
+            $framework->assets()->package('baz_package')
+                // this package inherits the default strategy
+                ->basePath('/images');
         };
 
-An added bonus of defining the enabled locales is that they are automatically
-added as a requirement of the :ref:`special _locale parameter <routing-locale-parameter>`.
-For example, if you define this value as ``['ar', 'he', 'ja', 'zh']``, the
-``_locale`` routing parameter will have an ``ar|he|ja|zh`` requirement. If some
-user makes requests with a locale not included in this option, they'll see a 404 error.
+.. note::
 
-set_content_language_from_locale
-................................
+    This parameter cannot be set at the same time as ``version`` or ``json_manifest_path``.
 
-**type**: ``boolean`` **default**: ``false``
+.. _reference-cache:
 
-If this option is set to ``true``, the response will have a ``Content-Language``
-HTTP header set with the ``Request`` locale.
+cache
+~~~~~
 
-set_locale_from_accept_language
-...............................
+.. _reference-cache-app:
 
-**type**: ``boolean`` **default**: ``false``
+app
+...
 
-If this option is set to ``true``, the ``Request`` locale will automatically be
-set to the value of the ``Accept-Language`` HTTP header.
+**type**: ``string`` **default**: ``cache.adapter.filesystem``
 
-When the ``_locale`` request attribute is passed, the ``Accept-Language`` header
-is ignored.
+The cache adapter used by the ``cache.app`` service. The FrameworkBundle
+ships with multiple adapters: ``cache.adapter.apcu``, ``cache.adapter.system``,
+``cache.adapter.filesystem``, ``cache.adapter.psr6``, ``cache.adapter.redis``,
+``cache.adapter.memcached``, ``cache.adapter.pdo`` and
+``cache.adapter.doctrine_dbal``.
 
-disallow_search_engine_index
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+There's also a special adapter called ``cache.adapter.array`` which stores
+contents in memory using a PHP array and it's used to disable caching (mostly on
+the ``dev`` environment).
 
-**type**: ``boolean`` **default**: ``true`` when the debug mode is enabled, ``false`` otherwise.
+.. tip::
 
-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.
-This option is a protection measure in case you accidentally publish your site
-in debug mode.
+    It might be tough to understand at the beginning, so to avoid confusion
+    remember that all pools perform the same actions but on different medium
+    given the adapter they are based on. Internally, a pool wraps the definition
+    of an adapter.
 
-.. _configuration-framework-trusted-hosts:
+default_doctrine_provider
+.........................
 
-trusted_hosts
-~~~~~~~~~~~~~
+**type**: ``string``
 
-**type**: ``array`` | ``string`` **default**: ``['%env(default::SYMFONY_TRUSTED_HOSTS)%']``
+The service name to use as your default Doctrine provider. The provider is
+available as the ``cache.default_doctrine_provider`` service.
 
-.. versionadded:: 7.2
+default_memcached_provider
+..........................
 
-    In Symfony 7.2, the default value of this option was changed from ``[]`` to the
-    value stored in the ``SYMFONY_TRUSTED_HOSTS`` environment variable.
+**type**: ``string`` **default**: ``memcached://localhost``
 
-A lot of different attacks have been discovered relying on inconsistencies
-in handling the ``Host`` header by various software (web servers, reverse
-proxies, web frameworks, etc.). Basically, every time the framework is
-generating an absolute URL (when sending an email to reset a password for
-instance), the host might have been manipulated by an attacker.
+The DSN to use by the Memcached provider. The provider is available as the ``cache.default_memcached_provider``
+service.
+
+default_pdo_provider
+....................
+
+**type**: ``string`` **default**: ``doctrine.dbal.default_connection``
+
+The service id of the database connection, which should be either a PDO or a
+Doctrine DBAL instance. The provider is available as the ``cache.default_pdo_provider``
+service.
+
+default_psr6_provider
+.....................
+
+**type**: ``string``
+
+The service name to use as your default PSR-6 provider. It is available as
+the ``cache.default_psr6_provider`` service.
+
+default_redis_provider
+......................
+
+**type**: ``string`` **default**: ``redis://localhost``
+
+The DSN to use by the Redis provider. The provider is available as the ``cache.default_redis_provider``
+service.
+
+directory
+.........
+
+**type**: ``string`` **default**: ``%kernel.cache_dir%/pools``
+
+The path to the cache directory used by services inheriting from the
+``cache.adapter.filesystem`` adapter (including ``cache.app``).
+
+pools
+.....
+
+**type**: ``array``
+
+A list of cache pools to be created by the framework extension.
 
 .. seealso::
 
-    You can read `HTTP Host header attacks`_ for more information about
-    these kinds of attacks.
+    For more information about how pools work, see :ref:`cache pools <component-cache-cache-pools>`.
 
-The Symfony :method:`Request::getHost() <Symfony\\Component\\HttpFoundation\\Request::getHost>`
-method might be vulnerable to some of these attacks because it depends on
-the configuration of your web server. One simple solution to avoid these
-attacks is to configure a list of hosts that your Symfony application can respond
-to. That's the purpose of this ``trusted_hosts`` option. If the incoming
-request's hostname doesn't match one of the regular expressions in this list,
-the application won't respond and the user will receive a 400 response.
+To configure a Redis cache pool with a default lifetime of 1 hour, do the following:
 
 .. configuration-block::
 
@@ -482,7 +647,11 @@ the application won't respond and the user will receive a 400 response.
 
         # config/packages/framework.yaml
         framework:
-            trusted_hosts:  ['^example\.com$', '^example\.org$']
+            cache:
+                pools:
+                    cache.mycache:
+                        adapter: cache.adapter.redis
+                        default_lifetime: 3600
 
     .. code-block:: xml
 
@@ -496,8 +665,13 @@ the application won't respond and the user will receive a 400 response.
                 http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
             <framework:config>
-                <framework:trusted-host>^example\.com$</framework:trusted-host>
-                <framework:trusted-host>^example\.org$</framework:trusted-host>
+                <framework:cache>
+                    <framework:pool
+                        name="cache.mycache"
+                        adapter="cache.adapter.redis"
+                        default-lifetime="3600"
+                    />
+                </framework:cache>
                 <!-- ... -->
             </framework:config>
         </container>
@@ -508,60 +682,119 @@ the application won't respond and the user will receive a 400 response.
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
-            $framework->trustedHosts(['^example\.com$', '^example\.org$']);
+            $framework->cache()
+                ->pool('cache.mycache')
+                    ->adapters(['cache.adapter.redis'])
+                    ->defaultLifetime(3600);
         };
 
-Hosts can also be configured to respond to any subdomain, via
-``^(.+\.)?example\.com$`` for instance.
+adapter
+"""""""
+
+**type**: ``string`` **default**: ``cache.app``
+
+The service name of the adapter to use. You can specify one of the default
+services that follow the pattern ``cache.adapter.[type]``. Alternatively you
+can specify another cache pool as base, which will make this pool inherit the
+settings from the base pool as defaults.
+
+.. note::
+
+    Your service needs to implement the ``Psr\Cache\CacheItemPoolInterface`` interface.
+
+clearer
+"""""""
+
+**type**: ``string``
+
+The cache clearer used to clear your PSR-6 cache.
+
+.. seealso::
+
+    For more information, see :class:`Symfony\\Component\\HttpKernel\\CacheClearer\\Psr6CacheClearer`.
+
+default_lifetime
+""""""""""""""""
+
+**type**: ``integer`` | ``string``
+
+Default lifetime of your cache items. Give an integer value to set the default
+lifetime in seconds. A string value could be ISO 8601 time interval, like ``"PT5M"``
+or a PHP date expression that is accepted by ``strtotime()``, like ``"5 minutes"``.
+
+If no value is provided, the cache adapter will fallback to the default value on
+the actual cache storage.
+
+.. _reference-cache-pools-name:
+
+name
+""""
+
+**type**: ``prototype``
+
+Name of the pool you want to create.
+
+.. note::
 
-In addition, you can also set the trusted hosts in the front controller
-using the ``Request::setTrustedHosts()`` method::
+    Your pool name must differ from ``cache.app`` or ``cache.system``.
 
-    // public/index.php
-    Request::setTrustedHosts(['^(.+\.)?example\.com$', '^(.+\.)?example\.org$']);
+provider
+""""""""
 
-The default value for this option is an empty array, meaning that the application
-can respond to any given host.
+**type**: ``string``
 
-.. seealso::
+Overwrite the default service name or DSN respectively, if you do not want to
+use what is configured as ``default_X_provider`` under ``cache``. See the
+description of the default provider setting above for information on how to
+specify your specific provider.
 
-    Read more about this in the `Security Advisory Blog post`_.
+public
+""""""
 
-.. _reference-framework-form:
+**type**: ``boolean`` **default**: ``false``
 
-form
-~~~~
+Whether your service should be public or not.
 
-.. _reference-form-enabled:
+tags
+""""
 
-enabled
-.......
+**type**: ``boolean`` | ``string`` **default**: ``null``
 
-**type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation
+Whether your service should be able to handle tags or not.
+Can also be the service id of another cache pool where tags will be stored.
 
-Whether to enable the form services or not in the service container. If
-you don't use forms, setting this to ``false`` may increase your application's
-performance because less services will be loaded into the container.
+.. _reference-cache-prefix-seed:
 
-This option will automatically be set to ``true`` when one of the child
-settings is configured.
+prefix_seed
+...........
 
-.. note::
+**type**: ``string`` **default**: ``_%kernel.project_dir%.%kernel.container_class%``
 
-    This will automatically enable the `validation`_.
+This value is used as part of the "namespace" generated for the
+cache item keys. A common practice is to use the unique name of the application
+(e.g. ``symfony.com``) because that prevents naming collisions when deploying
+multiple applications into the same path (on different servers) that share the
+same cache backend.
 
-.. seealso::
+It's also useful when using `blue/green deployment`_ strategies and more
+generally, when you need to abstract out the actual deployment directory (for
+example, when warming caches offline).
 
-    For more details, see :doc:`/forms`.
+.. note::
 
-.. _reference-form-field-name:
+    The ``prefix_seed`` option is used at compile time. This means
+    that any change made to this value after container's compilation
+    will have no effect.
 
-field_name
-..........
+.. _reference-cache-system:
 
-**type**: ``string`` **default**: ``_token``
+system
+......
 
-This is the field name that you should give to the CSRF token field of your forms.
+**type**: ``string`` **default**: ``cache.adapter.system``
+
+The cache adapter used by the ``cache.system`` service. It supports the same
+adapters available for the ``cache.app`` service.
 
 .. _reference-framework-csrf-protection:
 
@@ -621,48 +854,47 @@ If you're using forms, but want to avoid starting your session (e.g. using
 forms in an API-only website), ``csrf_protection`` will need to be set to
 ``false``.
 
-.. _config-framework-error_controller:
-
-error_controller
-~~~~~~~~~~~~~~~~
+.. _config-framework-default_locale:
 
-**type**: ``string`` **default**: ``error_controller``
+default_locale
+~~~~~~~~~~~~~~
 
-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`)
-renders specific templates under different error conditions (see
-:doc:`/controller/error_pages`).
+**type**: ``string`` **default**: ``en``
 
-esi
-~~~
+The default locale is used if no ``_locale`` routing parameter has been
+set. It is available with the
+:method:`Request::getDefaultLocale <Symfony\\Component\\HttpFoundation\\Request::getDefaultLocale>`
+method.
 
 .. seealso::
 
-    You can read more about Edge Side Includes (ESI) in :ref:`edge-side-includes`.
-
-.. _reference-esi-enabled:
+    You can read more information about the default locale in
+    :ref:`translation-default-locale`.
 
-enabled
-.......
+.. _reference-translator-enabled-locales:
+.. _reference-enabled-locales:
 
-**type**: ``boolean`` **default**: ``false``
+enabled_locales
+...............
 
-Whether to enable the edge side includes support in the framework.
+**type**: ``array`` **default**: ``[]`` (empty array = enable all locales)
 
-You can also set ``esi`` to ``true`` to enable it:
+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:
-            esi: true
+            enabled_locales: ['en', 'es']
 
     .. code-block:: xml
 
-        <!-- config/packages/framework.xml -->
+        <!-- config/packages/translation.xml -->
         <?xml version="1.0" encoding="UTF-8" ?>
         <container xmlns="http://symfony.com/schema/dic/services"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -672,74 +904,86 @@ You can also set ``esi`` to ``true`` to enable it:
                 http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
             <framework:config>
-                <framework:esi/>
+                <enabled-locale>en</enabled-locale>
+                <enabled-locale>es</enabled-locale>
             </framework:config>
         </container>
 
     .. code-block:: php
 
-        // config/packages/framework.php
+        // config/packages/translation.php
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
-            $framework->esi()->enabled(true);
+            $framework->enabledLocales(['en', 'es']);
         };
 
-fragments
-~~~~~~~~~
+An added bonus of defining the enabled locales is that they are automatically
+added as a requirement of the :ref:`special _locale parameter <routing-locale-parameter>`.
+For example, if you define this value as ``['ar', 'he', 'ja', 'zh']``, the
+``_locale`` routing parameter will have an ``ar|he|ja|zh`` requirement. If some
+user makes requests with a locale not included in this option, they'll see a 404 error.
 
-.. seealso::
+set_content_language_from_locale
+................................
 
-    Learn more about fragments in the
-    :ref:`HTTP Cache article <http_cache-fragments>`.
+**type**: ``boolean`` **default**: ``false``
 
-.. _reference-fragments-enabled:
+If this option is set to ``true``, the response will have a ``Content-Language``
+HTTP header set with the ``Request`` locale.
 
-enabled
-.......
+set_locale_from_accept_language
+...............................
 
 **type**: ``boolean`` **default**: ``false``
 
-Whether to enable the fragment listener or not. The fragment listener is
-used to render ESI fragments independently of the rest of the page.
+If this option is set to ``true``, the ``Request`` locale will automatically be
+set to the value of the ``Accept-Language`` HTTP header.
 
-This setting is automatically set to ``true`` when one of the child settings
-is configured.
+When the ``_locale`` request attribute is passed, the ``Accept-Language`` header
+is ignored.
 
-hinclude_default_template
-.........................
+disallow_search_engine_index
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-**type**: ``string`` **default**: ``null``
+**type**: ``boolean`` **default**: ``true`` when the debug mode is enabled, ``false`` otherwise.
 
-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.
+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.
+This option is a protection measure in case you accidentally publish your site
+in debug mode.
 
-.. seealso::
+.. _config-framework-error_controller:
 
-    See :ref:`templates-hinclude` for more information about hinclude.
+error_controller
+~~~~~~~~~~~~~~~~
 
-.. _reference-fragments-path:
+**type**: ``string`` **default**: ``error_controller``
 
-path
-....
+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`)
+renders specific templates under different error conditions (see
+:doc:`/controller/error_pages`).
 
-**type**: ``string`` **default**: ``/_fragment``
+esi
+~~~
 
-The path prefix for fragments. The fragment listener will only be executed
-when the request starts with this path.
+.. seealso::
 
-.. _reference-http-client:
+    You can read more about Edge Side Includes (ESI) in :ref:`edge-side-includes`.
 
-http_client
-~~~~~~~~~~~
+.. _reference-esi-enabled:
 
-When the HttpClient component is installed, an HTTP client is available
-as a service named ``http_client`` or using the autowiring alias
-:class:`Symfony\\Contracts\\HttpClient\\HttpClientInterface`.
+enabled
+.......
 
-.. _reference-http-client-default-options:
+**type**: ``boolean`` **default**: ``false``
 
-This service can be configured using ``framework.http_client.default_options``:
+Whether to enable the edge side includes support in the framework.
+
+You can also set ``esi`` to ``true`` to enable it:
 
 .. configuration-block::
 
@@ -747,12 +991,7 @@ This service can be configured using ``framework.http_client.default_options``:
 
         # config/packages/framework.yaml
         framework:
-            # ...
-            http_client:
-                max_host_connections: 10
-                default_options:
-                    headers: { 'X-Powered-By': 'ACME App' }
-                    max_redirects: 7
+            esi: true
 
     .. code-block:: xml
 
@@ -766,61 +1005,43 @@ This service can be configured using ``framework.http_client.default_options``:
                 http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
             <framework:config>
-                <framework:http-client max-host-connections="10">
-                    <framework:default-options max-redirects="7">
-                        <framework:header name="X-Powered-By">ACME App</framework:header>
-                    </framework:default-options>
-                </framework:http-client>
+                <framework:esi/>
             </framework:config>
         </container>
 
     .. code-block:: php
 
         // config/packages/framework.php
-        $container->loadFromExtension('framework', [
-            'http_client' => [
-                'max_host_connections' => 10,
-                'default_options' => [
-                    'headers' => [
-                        'X-Powered-By' => 'ACME App',
-                    ],
-                    'max_redirects' => 7,
-                ],
-            ],
-        ]);
+        use Symfony\Config\FrameworkConfig;
 
-    .. code-block:: php-standalone
+        return static function (FrameworkConfig $framework): void {
+            $framework->esi()->enabled(true);
+        };
 
-        $client = HttpClient::create([
-            'headers' => [
-                'X-Powered-By' => 'ACME App',
-            ],
-            'max_redirects' => 7,
-        ], 10);
+.. _framework_exceptions:
 
-.. _reference-http-client-scoped-clients:
+exceptions
+~~~~~~~~~~
 
-Multiple pre-configured HTTP client services can be defined, each with its
-service name defined as a key under ``scoped_clients``. Scoped clients inherit
-the default options defined for the ``http_client`` service. You can override
-these options and can define a few others:
+**type**: ``array``
+
+Defines the :ref:`log level </logging>` and HTTP status code applied to the
+exceptions that match the given exception class:
 
 .. configuration-block::
 
     .. code-block:: yaml
 
-        # config/packages/framework.yaml
-        framework:
-            # ...
-            http_client:
-                scoped_clients:
-                    my_api.client:
-                        auth_bearer: secret_bearer_token
-                        # ...
+        # config/packages/exceptions.yaml
+        framework:
+            exceptions:
+                Symfony\Component\HttpKernel\Exception\BadRequestHttpException:
+                    log_level: 'debug'
+                    status_code: 422
 
     .. code-block:: xml
 
-        <!-- config/packages/framework.xml -->
+        <!-- config/packages/exceptions.xml -->
         <?xml version="1.0" encoding="UTF-8" ?>
         <container xmlns="http://symfony.com/schema/dic/services"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -830,808 +1051,895 @@ these options and can define a few others:
                 http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
             <framework:config>
-                <framework:http-client>
-                    <framework:scoped-client name="my_api.client" auth-bearer="secret_bearer_token"/>
-                </framework:http-client>
+                <framework:exception
+                    class="Symfony\Component\HttpKernel\Exception\BadRequestHttpException"
+                    log-level="debug"
+                    status-code="422"
+                />
+                <!-- ... -->
             </framework:config>
         </container>
 
     .. code-block:: php
 
-        // config/packages/framework.php
-        $container->loadFromExtension('framework', [
-            'http_client' => [
-                'scoped_clients' => [
-                    'my_api.client' => [
-                        'auth_bearer' => 'secret_bearer_token',
-                        // ...
-                    ],
-                ],
-            ],
-        ]);
+        // config/packages/exceptions.php
+        use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
+        use Symfony\Config\FrameworkConfig;
 
-    .. code-block:: php-standalone
+        return static function (FrameworkConfig $framework): void {
+            $framework->exception(BadRequestHttpException::class)
+                ->logLevel('debug')
+                ->statusCode(422)
+            ;
+        };
 
-        $client = HttpClient::createForBaseUri('https://...', [
-            'auth_bearer' => 'secret_bearer_token',
-            // ...
-        ]);
+The order in which you configure exceptions is important because Symfony will
+use the configuration of the first exception that matches ``instanceof``:
 
-Options defined for scoped clients apply only to URLs that match either their
-`base_uri`_ or the `scope`_ option when it is defined. Non-matching URLs always
-use default options.
+.. code-block:: yaml
 
-Each scoped client also defines a corresponding named autowiring alias.
-If you use for example
-``Symfony\Contracts\HttpClient\HttpClientInterface $myApiClient``
-as the type and name of an argument, autowiring will inject the ``my_api.client``
-service into your autowired classes.
+        # config/packages/exceptions.yaml
+        framework:
+            exceptions:
+                Exception:
+                    log_level: 'debug'
+                    status_code: 404
+                # The following configuration will never be used because \RuntimeException extends \Exception
+                RuntimeException:
+                    log_level: 'debug'
+                    status_code: 422
 
-auth_basic
-..........
+You can map a status code and a set of headers to an exception thanks
+to the ``#[WithHttpStatus]`` attribute on the exception class::
 
-**type**: ``string``
+    namespace App\Exception;
 
-The username and password used to create the ``Authorization`` HTTP header
-used in HTTP Basic authentication. The value of this option must follow the
-format ``username:password``.
+    use Symfony\Component\HttpKernel\Attribute\WithHttpStatus;
 
-auth_bearer
-...........
+    #[WithHttpStatus(422, [
+       'Retry-After' => 10,
+       'X-Custom-Header' => 'header-value',
+    ])]
+    class CustomException extends \Exception
+    {
+    }
 
-**type**: ``string``
+It is also possible to map a log level on a custom exception class using
+the ``#[WithLogLevel]`` attribute::
 
-The token used to create the ``Authorization`` HTTP header used in HTTP Bearer
-authentication (also called token authentication).
+    namespace App\Exception;
 
-auth_ntlm
-.........
+    use Psr\Log\LogLevel;
+    use Symfony\Component\HttpKernel\Attribute\WithLogLevel;
 
-**type**: ``string``
+    #[WithLogLevel(LogLevel::WARNING)]
+    class CustomException extends \Exception
+    {
+    }
 
-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
-using the cURL-based transport.
+The attributes can also be added to interfaces directly::
 
-.. _reference-http-client-base-uri:
+    namespace App\Exception;
 
-base_uri
-........
+    use Symfony\Component\HttpKernel\Attribute\WithHttpStatus;
 
-**type**: ``string``
+    #[WithHttpStatus(422)]
+    interface CustomExceptionInterface
+    {
+    }
 
-URI that is merged into relative URIs, following the rules explained in the
-`RFC 3986`_ standard. This is useful when all the requests you make share a
-common prefix (e.g. ``https://api.github.com/``) so you can avoid adding it to
-every request.
+    class CustomException extends \Exception implements CustomExceptionInterface
+    {
+    }
 
-Here are some common examples of how ``base_uri`` merging works in practice:
+.. versionadded:: 7.1
 
-==========================  ==================  =============================
-``base_uri``                Relative URI        Actual Requested URI
-==========================  ==================  =============================
-http://example.org          /bar                http://example.org/bar
-http://example.org/foo      /bar                http://example.org/bar
-http://example.org/foo      bar                 http://example.org/bar
-http://example.org/foo/     /bar                http://example.org/bar
-http://example.org/foo/     bar                 http://example.org/foo/bar
-http://example.org          http://symfony.com  http://symfony.com
-http://example.org/?bar     bar                 http://example.org/bar
-http://example.org/api/v4   /bar                http://example.org/bar
-http://example.org/api/v4/  /bar                http://example.org/bar
-http://example.org/api/v4   bar                 http://example.org/api/bar
-http://example.org/api/v4/  bar                 http://example.org/api/v4/bar
-==========================  ==================  =============================
+    Support to use ``#[WithHttpStatus]`` and ``#[WithLogLevel]`` attributes
+    on interfaces was introduced in Symfony 7.1.
 
-bindto
-......
+.. _reference-framework-form:
 
-**type**: ``string``
+form
+~~~~
 
-A network interface name, IP address, a host name or a UNIX socket to use as the
-outgoing network interface.
+.. _reference-form-enabled:
 
-buffer
-......
+enabled
+.......
 
-**type**: ``boolean`` | ``Closure``
+**type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation
 
-Buffering the response means that you can access its content multiple times
-without performing the request again. Buffering is enabled by default when the
-content type of the response is ``text/*``, ``application/json`` or ``application/xml``.
+Whether to enable the form services or not in the service container. If
+you don't use forms, setting this to ``false`` may increase your application's
+performance because less services will be loaded into the container.
 
-If this option is a boolean value, the response is buffered when the value is
-``true``. If this option is a closure, the response is buffered when the
-returned value is ``true`` (the closure receives as argument an array with the
-response headers).
+This option will automatically be set to ``true`` when one of the child
+settings is configured.
 
-cafile
-......
+.. note::
 
-**type**: ``string``
+    This will automatically enable the `validation`_.
 
-The path of the certificate authority file that contains one or more
-certificates used to verify the other servers' certificates.
+.. seealso::
 
-capath
-......
+    For more details, see :doc:`/forms`.
 
-**type**: ``string``
+.. _reference-form-field-name:
 
-The path to a directory that contains one or more certificate authority files.
+field_name
+..........
 
-ciphers
+**type**: ``string`` **default**: ``_token``
+
+This is the field name that you should give to the CSRF token field of your forms.
+
+fragments
+~~~~~~~~~
+
+.. seealso::
+
+    Learn more about fragments in the
+    :ref:`HTTP Cache article <http_cache-fragments>`.
+
+.. _reference-fragments-enabled:
+
+enabled
 .......
 
-**type**: ``string``
+**type**: ``boolean`` **default**: ``false``
 
-A list of the names of the ciphers allowed for the TLS connections. They
-can be separated by colons, commas or spaces (e.g. ``'RC4-SHA:TLS13-AES-128-GCM-SHA256'``).
+Whether to enable the fragment listener or not. The fragment listener is
+used to render ESI fragments independently of the rest of the page.
 
-crypto_method
-.............
+This setting is automatically set to ``true`` when one of the child settings
+is configured.
 
-**type**: ``integer``
+hinclude_default_template
+.........................
 
-The minimum version of TLS to accept. The value must be one of the
-``STREAM_CRYPTO_METHOD_TLSv*_CLIENT`` constants defined by PHP.
+**type**: ``string`` **default**: ``null``
 
-.. _reference-http-client-retry-delay:
+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.
 
-delay
-.....
+.. seealso::
 
-**type**: ``integer`` **default**: ``1000``
+    See :ref:`templates-hinclude` for more information about hinclude.
 
-The initial delay in milliseconds used to compute the waiting time between retries.
+.. _reference-fragments-path:
+
+path
+....
+
+**type**: ``string`` **default**: ``/_fragment``
+
+The path prefix for fragments. The fragment listener will only be executed
+when the request starts with this path.
+
+handle_all_throwables
+~~~~~~~~~~~~~~~~~~~~~
+
+**type**: ``boolean`` **default**: ``true``
+
+When set to ``true``, the Symfony kernel will catch all ``\Throwable`` exceptions
+thrown by the application and will turn them into HTTP responses.
+
+html_sanitizer
+~~~~~~~~~~~~~~
+
+The ``html_sanitizer`` option (and its children) are used to configure
+custom HTML sanitizers. Read more about the options in the
+:ref:`HTML sanitizer documentation <html-sanitizer-configuration>`.
+
+.. _configuration-framework-http_cache:
+
+http_cache
+~~~~~~~~~~
+
+allow_reload
+............
+
+**type**: ``string``
 
-.. _reference-http-client-retry-enabled:
+Specifies whether the client can force a cache reload by including a
+Cache-Control "no-cache" directive in the request. Set it to ``true``
+for compliance with RFC 2616. (default: false)
 
-enabled
-.......
+allow_revalidate
+................
 
-**type**: ``boolean`` **default**: ``false``
+**type**: ``string``
 
-Whether to enable the support for retry failed HTTP request or not.
-This setting is automatically set to true when one of the child settings is configured.
+Specifies whether the client can force a cache revalidate by including a
+Cache-Control "max-age=0" directive in the request. Set it to ``true``
+for compliance with RFC 2616. (default: false)
 
-extra
+debug
 .....
 
-**type**: ``array``
-
-Arbitrary additional data to pass to the HTTP client for further use.
-This can be particularly useful when :ref:`decorating an existing client <extensibility>`.
+**type**: ``boolean`` **default**: ``%kernel.debug%``
 
-.. _http-headers:
+If true, exceptions are thrown when things go wrong. Otherwise, the cache will
+try to carry on and deliver a meaningful response.
 
-headers
-.......
+default_ttl
+...........
 
-**type**: ``array``
+**type**: ``integer``
 
-An associative array of the HTTP headers added before making the request. This
-value must use the format ``['header-name' => 'value0, value1, ...']``.
+The number of seconds that a cache entry should be considered fresh when no
+explicit freshness information is provided in a response. Explicit
+Cache-Control or Expires headers override this value. (default: 0)
 
-.. _reference-http-client-retry-http-codes:
+enabled
+.......
 
-http_codes
-..........
+**type**: ``boolean`` **default**: ``false``
 
-**type**: ``array`` **default**: :method:`Symfony\\Component\\HttpClient\\Retry\\GenericRetryStrategy::DEFAULT_RETRY_STATUS_CODES`
+private_headers
+...............
 
-The list of HTTP status codes that triggers a retry of the request.
+**type**: ``array``
 
-http_version
-............
+Set of request headers that trigger "private" cache-control behavior on responses
+that don't explicitly state whether the response is public or private via a
+Cache-Control directive. (default: Authorization and Cookie)
 
-**type**: ``string`` | ``null`` **default**: ``null``
+skip_response_headers
+.....................
 
-The HTTP version to use, typically ``'1.1'``  or ``'2.0'``. Leave it to ``null``
-to let Symfony select the best version automatically.
+**type**: ``array`` **default**: ``Set-Cookie``
 
-.. _reference-http-client-retry-jitter:
+Set of response headers that will never be cached even when the response is cacheable
+and public.
 
-jitter
-......
+stale_if_error
+..............
 
-**type**: ``float`` **default**: ``0.1`` (must be between 0.0 and 1.0)
+**type**: ``integer``
 
-This option adds some randomness to the delay. It's useful to avoid sending
-multiple requests to the server at the exact same time. The randomness is
-calculated as ``delay * jitter``. For example: if delay is ``1000ms`` and jitter
-is ``0.2``, the actual delay will be a number between ``800`` and ``1200`` (1000 +/- 20%).
+Specifies the default number of seconds (the granularity is the second) during
+which the cache can serve a stale response when an error is encountered
+(default: 60). This setting is overridden by the stale-if-error HTTP
+Cache-Control extension (see RFC 5861).
 
-local_cert
-..........
+stale_while_revalidate
+......................
 
-**type**: ``string``
+**type**: ``integer``
 
-The path to a file that contains the `PEM formatted`_ certificate used by the
-HTTP client. This is often combined with the ``local_pk`` and ``passphrase``
-options.
+Specifies the default number of seconds (the granularity is the second as the
+Response TTL precision is a second) during which the cache can immediately return
+a stale response while it revalidates it in the background (default: 2).
+This setting is overridden by the stale-while-revalidate HTTP Cache-Control
+extension (see RFC 5861).
 
-local_pk
-........
+trace_header
+............
 
 **type**: ``string``
 
-The path of a file that contains the `PEM formatted`_ private key of the
-certificate defined in the ``local_cert`` option.
+Header name to use for traces. (default: X-Symfony-Cache)
 
-.. _reference-http-client-retry-max-delay:
+trace_level
+...........
 
-max_delay
-.........
+**type**: ``string`` **possible values**: ``'none'``, ``'short'`` or ``'full'``
 
-**type**: ``integer`` **default**: ``0``
+For 'short', a concise trace of the main request will be added as an HTTP header.
+'full' will add traces for all requests (including ESI subrequests).
+(default: 'full' if in debug; 'none' otherwise)
 
-The maximum amount of milliseconds initial to wait between retries.
-Use ``0`` to not limit the duration.
+.. _reference-http-client:
 
-max_duration
-............
+http_client
+~~~~~~~~~~~
 
-**type**: ``float`` **default**: ``0``
+When the HttpClient component is installed, an HTTP client is available
+as a service named ``http_client`` or using the autowiring alias
+:class:`Symfony\\Contracts\\HttpClient\\HttpClientInterface`.
 
-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.
+.. _reference-http-client-default-options:
 
-max_host_connections
-....................
+This service can be configured using ``framework.http_client.default_options``:
 
-**type**: ``integer`` **default**: ``6``
+.. configuration-block::
 
-Defines the maximum amount of simultaneously open connections to a single host
-(considering a "host" the same as a "host name + port number" pair). This limit
-also applies for proxy connections, where the proxy is considered to be the host
-for which this limit is applied.
+    .. code-block:: yaml
 
-max_redirects
-.............
+        # config/packages/framework.yaml
+        framework:
+            # ...
+            http_client:
+                max_host_connections: 10
+                default_options:
+                    headers: { 'X-Powered-By': 'ACME App' }
+                    max_redirects: 7
 
-**type**: ``integer`` **default**: ``20``
+    .. code-block:: xml
 
-The maximum number of redirects to follow. Use ``0`` to not follow any
-redirection.
+        <!-- config/packages/framework.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
-.. _reference-http-client-retry-max-retries:
+            <framework:config>
+                <framework:http-client max-host-connections="10">
+                    <framework:default-options max-redirects="7">
+                        <framework:header name="X-Powered-By">ACME App</framework:header>
+                    </framework:default-options>
+                </framework:http-client>
+            </framework:config>
+        </container>
 
-max_retries
-...........
+    .. code-block:: php
 
-**type**: ``integer`` **default**: ``3``
+        // config/packages/framework.php
+        $container->loadFromExtension('framework', [
+            'http_client' => [
+                'max_host_connections' => 10,
+                'default_options' => [
+                    'headers' => [
+                        'X-Powered-By' => 'ACME App',
+                    ],
+                    'max_redirects' => 7,
+                ],
+            ],
+        ]);
 
-The maximum number of retries for failing requests. When the maximum is reached,
-the client returns the last received response.
+    .. code-block:: php-standalone
 
-.. _reference-http-client-retry-multiplier:
+        $client = HttpClient::create([
+            'headers' => [
+                'X-Powered-By' => 'ACME App',
+            ],
+            'max_redirects' => 7,
+        ], 10);
 
-multiplier
-..........
+.. _reference-http-client-scoped-clients:
 
-**type**: ``float`` **default**: ``2``
+Multiple pre-configured HTTP client services can be defined, each with its
+service name defined as a key under ``scoped_clients``. Scoped clients inherit
+the default options defined for the ``http_client`` service. You can override
+these options and can define a few others:
 
-This value is multiplied to the delay each time a retry occurs, to distribute
-retries in time instead of making all of them sequentially.
+.. configuration-block::
 
-no_proxy
-........
+    .. code-block:: yaml
 
-**type**: ``string`` | ``null`` **default**: ``null``
+        # config/packages/framework.yaml
+        framework:
+            # ...
+            http_client:
+                scoped_clients:
+                    my_api.client:
+                        auth_bearer: secret_bearer_token
+                        # ...
 
-A comma separated list of hosts that do not require a proxy to be reached, even
-if one is configured. Use the ``'*'`` wildcard to match all hosts and an empty
-string to match none (disables the proxy).
+    .. code-block:: xml
 
-passphrase
-..........
+        <!-- config/packages/framework.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
-**type**: ``string``
+            <framework:config>
+                <framework:http-client>
+                    <framework:scoped-client name="my_api.client" auth-bearer="secret_bearer_token"/>
+                </framework:http-client>
+            </framework:config>
+        </container>
 
-The passphrase used to encrypt the certificate stored in the file defined in the
-``local_cert`` option.
+    .. code-block:: php
 
-peer_fingerprint
-................
+        // config/packages/framework.php
+        $container->loadFromExtension('framework', [
+            'http_client' => [
+                'scoped_clients' => [
+                    'my_api.client' => [
+                        'auth_bearer' => 'secret_bearer_token',
+                        // ...
+                    ],
+                ],
+            ],
+        ]);
 
-**type**: ``array``
+    .. code-block:: php-standalone
 
-When negotiating a TLS connection, the server sends a certificate
-indicating its identity. A public key is extracted from this certificate and if
-it does not exactly match any of the public keys provided in this option, the
-connection is aborted before sending or receiving any data.
+        $client = HttpClient::createForBaseUri('https://...', [
+            'auth_bearer' => 'secret_bearer_token',
+            // ...
+        ]);
 
-The value of this option is an associative array of ``algorithm => hash``
-(e.g ``['pin-sha256' => '...']``).
+Options defined for scoped clients apply only to URLs that match either their
+`base_uri`_ or the `scope`_ option when it is defined. Non-matching URLs always
+use default options.
 
-proxy
-.....
+Each scoped client also defines a corresponding named autowiring alias.
+If you use for example
+``Symfony\Contracts\HttpClient\HttpClientInterface $myApiClient``
+as the type and name of an argument, autowiring will inject the ``my_api.client``
+service into your autowired classes.
 
-**type**: ``string`` | ``null``
+auth_basic
+..........
 
-The HTTP proxy to use to make the requests. Leave it to ``null`` to detect the
-proxy automatically based on your system configuration.
+**type**: ``string``
 
-query
-.....
+The username and password used to create the ``Authorization`` HTTP header
+used in HTTP Basic authentication. The value of this option must follow the
+format ``username:password``.
 
-**type**: ``array``
+auth_bearer
+...........
 
-An associative array of the query string values added to the URL before making
-the request. This value must use the format ``['parameter-name' => parameter-value, ...]``.
+**type**: ``string``
 
-rate_limiter
-............
+The token used to create the ``Authorization`` HTTP header used in HTTP Bearer
+authentication (also called token authentication).
 
-**type**: ``string``
+auth_ntlm
+.........
 
-The service ID of the rate limiter used to limit the number of HTTP requests
-within a certain period. The service must implement the
-:class:`Symfony\\Component\\RateLimiter\\LimiterInterface`.
+**type**: ``string``
 
-.. versionadded:: 7.1
+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
+using the cURL-based transport.
 
-    The ``rate_limiter`` option was introduced in Symfony 7.1.
+.. _reference-http-client-base-uri:
 
-resolve
-.......
+base_uri
+........
 
-**type**: ``array``
+**type**: ``string``
 
-A list of hostnames and their IP addresses to pre-populate the DNS cache used by
-the HTTP client in order to avoid a DNS lookup for those hosts. This option is
-useful to improve security when IPs are checked before the URL is passed to the
-client and to make your tests easier.
+URI that is merged into relative URIs, following the rules explained in the
+`RFC 3986`_ standard. This is useful when all the requests you make share a
+common prefix (e.g. ``https://api.github.com/``) so you can avoid adding it to
+every request.
 
-The value of this option is an associative array of ``domain => IP address``
-(e.g ``['symfony.com' => '46.137.106.254', ...]``).
+Here are some common examples of how ``base_uri`` merging works in practice:
 
-.. _reference-http-client-retry-failed:
+==========================  ==================  =============================
+``base_uri``                Relative URI        Actual Requested URI
+==========================  ==================  =============================
+http://example.org          /bar                http://example.org/bar
+http://example.org/foo      /bar                http://example.org/bar
+http://example.org/foo      bar                 http://example.org/bar
+http://example.org/foo/     /bar                http://example.org/bar
+http://example.org/foo/     bar                 http://example.org/foo/bar
+http://example.org          http://symfony.com  http://symfony.com
+http://example.org/?bar     bar                 http://example.org/bar
+http://example.org/api/v4   /bar                http://example.org/bar
+http://example.org/api/v4/  /bar                http://example.org/bar
+http://example.org/api/v4   bar                 http://example.org/api/bar
+http://example.org/api/v4/  bar                 http://example.org/api/v4/bar
+==========================  ==================  =============================
 
-retry_failed
-............
+bindto
+......
 
-**type**: ``array``
+**type**: ``string``
 
-This option configures the behavior of the HTTP client when some request fails,
-including which types of requests to retry and how many times. The behavior is
-defined with the following options:
+A network interface name, IP address, a host name or a UNIX socket to use as the
+outgoing network interface.
 
-* :ref:`delay <reference-http-client-retry-delay>`
-* :ref:`http_codes <reference-http-client-retry-http-codes>`
-* :ref:`jitter <reference-http-client-retry-jitter>`
-* :ref:`max_delay <reference-http-client-retry-max-delay>`
-* :ref:`max_retries <reference-http-client-retry-max-retries>`
-* :ref:`multiplier <reference-http-client-retry-multiplier>`
+buffer
+......
 
-.. code-block:: yaml
+**type**: ``boolean`` | ``Closure``
 
-    # config/packages/framework.yaml
-    framework:
-        # ...
-        http_client:
-            # ...
-            default_options:
-                retry_failed:
-                    # retry_strategy: app.custom_strategy
-                    http_codes:
-                        0: ['GET', 'HEAD']   # retry network errors if request method is GET or HEAD
-                        429: true            # retry all responses with 429 status code
-                        500: ['GET', 'HEAD']
-                    max_retries: 2
-                    delay: 1000
-                    multiplier: 3
-                    max_delay: 5000
-                    jitter: 0.3
+Buffering the response means that you can access its content multiple times
+without performing the request again. Buffering is enabled by default when the
+content type of the response is ``text/*``, ``application/json`` or ``application/xml``.
 
-            scoped_clients:
-                my_api.client:
-                    # ...
-                    retry_failed:
-                        max_retries: 4
+If this option is a boolean value, the response is buffered when the value is
+``true``. If this option is a closure, the response is buffered when the
+returned value is ``true`` (the closure receives as argument an array with the
+response headers).
 
-retry_strategy
-..............
+cafile
+......
 
 **type**: ``string``
 
-The service is used to decide if a request should be retried and to compute the
-time to wait between retries. By default, it uses an instance of
-:class:`Symfony\\Component\\HttpClient\\Retry\\GenericRetryStrategy` configured
-with ``http_codes``, ``delay``, ``max_delay``, ``multiplier`` and ``jitter``
-options. This class has to implement
-:class:`Symfony\\Component\\HttpClient\\Retry\\RetryStrategyInterface`.
+The path of the certificate authority file that contains one or more
+certificates used to verify the other servers' certificates.
 
-scope
-.....
+capath
+......
 
 **type**: ``string``
 
-For scoped clients only: the regular expression that the URL must match before
-applying all other non-default options. By default, the scope is derived from
-`base_uri`_.
+The path to a directory that contains one or more certificate authority files.
 
-timeout
+ciphers
 .......
 
-**type**: ``float`` **default**: depends on your PHP config
-
-Time, in seconds, to wait for network activity. If the connection is idle for longer, a
-:class:`Symfony\\Component\\HttpClient\\Exception\\TransportException` is thrown.
-Its default value is the same as the value of PHP's `default_socket_timeout`_
-config option.
-
-verify_host
-...........
+**type**: ``string``
 
-**type**: ``boolean`` **default**: ``true``
+A list of the names of the ciphers allowed for the TLS connections. They
+can be separated by colons, commas or spaces (e.g. ``'RC4-SHA:TLS13-AES-128-GCM-SHA256'``).
 
-If ``true``, the certificate sent by other servers is verified to ensure that
-their common name matches the host included in the URL. This is usually
-combined with ``verify_peer`` to also verify the certificate authenticity.
+crypto_method
+.............
 
-verify_peer
-...........
+**type**: ``integer``
 
-**type**: ``boolean`` **default**: ``true``
+The minimum version of TLS to accept. The value must be one of the
+``STREAM_CRYPTO_METHOD_TLSv*_CLIENT`` constants defined by PHP.
 
-If ``true``, the certificate sent by other servers when negotiating a TLS
-connection is verified for authenticity. Authenticating the certificate is not
-enough to be sure about the server, so you should combine this with the
-``verify_host`` option.
+.. _reference-http-client-retry-delay:
 
-html_sanitizer
-~~~~~~~~~~~~~~
+delay
+.....
 
-The ``html_sanitizer`` option (and its children) are used to configure
-custom HTML sanitizers. Read more about the options in the
-:ref:`HTML sanitizer documentation <html-sanitizer-configuration>`.
+**type**: ``integer`` **default**: ``1000``
 
-profiler
-~~~~~~~~
+The initial delay in milliseconds used to compute the waiting time between retries.
 
-.. _reference-profiler-enabled:
+.. _reference-http-client-retry-enabled:
 
 enabled
 .......
 
 **type**: ``boolean`` **default**: ``false``
 
-The profiler can be enabled by setting this option to ``true``. When you
-install it using Symfony Flex, the profiler is enabled in the ``dev``
-and ``test`` environments.
+Whether to enable the support for retry failed HTTP request or not.
+This setting is automatically set to true when one of the child settings is configured.
 
-.. note::
+extra
+.....
 
-    The profiler works independently from the Web Developer Toolbar, see
-    the :doc:`WebProfilerBundle configuration </reference/configuration/web_profiler>`
-    on how to disable/enable the toolbar.
+**type**: ``array``
 
-collect
-.......
+Arbitrary additional data to pass to the HTTP client for further use.
+This can be particularly useful when :ref:`decorating an existing client <extensibility>`.
 
-**type**: ``boolean`` **default**: ``true``
+.. _http-headers:
 
-This option configures the way the profiler behaves when it is enabled. If set
-to ``true``, the profiler collects data for all requests. If you want to only
-collect information on-demand, you can set the ``collect`` flag to ``false`` and
-activate the data collectors manually::
+headers
+.......
 
-    $profiler->enable();
+**type**: ``array``
 
-collect_parameter
-.................
+An associative array of the HTTP headers added before making the request. This
+value must use the format ``['header-name' => 'value0, value1, ...']``.
 
-**type**: ``string`` **default**: ``null``
+.. _reference-http-client-retry-http-codes:
 
-This specifies name of a query parameter, a body parameter or a request attribute
-used to enable or disable collection of data by the profiler for each request.
-Combine it with the ``collect`` option to enable/disable the profiler on demand:
+http_codes
+..........
 
-* If the ``collect`` option is set to ``true`` but this parameter exists in a
-  request and has any value other than ``true``, ``yes``, ``on`` or ``1``, the
-  request data will not be collected;
-* If the ``collect`` option is set to ``false``, but this parameter exists in a
-  request and has value of ``true``, ``yes``, ``on`` or ``1``, the request data
-  will be collected.
+**type**: ``array`` **default**: :method:`Symfony\\Component\\HttpClient\\Retry\\GenericRetryStrategy::DEFAULT_RETRY_STATUS_CODES`
 
-only_exceptions
-...............
+The list of HTTP status codes that triggers a retry of the request.
 
-**type**: ``boolean`` **default**: ``false``
+http_version
+............
 
-When this is set to ``true``, the profiler will only be enabled when an
-exception is thrown during the handling of the request.
+**type**: ``string`` | ``null`` **default**: ``null``
 
-.. _only_master_requests:
+The HTTP version to use, typically ``'1.1'``  or ``'2.0'``. Leave it to ``null``
+to let Symfony select the best version automatically.
 
-only_main_requests
-..................
+.. _reference-http-client-retry-jitter:
+
+jitter
+......
 
-**type**: ``boolean`` **default**: ``false``
+**type**: ``float`` **default**: ``0.1`` (must be between 0.0 and 1.0)
 
-When this is set to ``true``, the profiler will only be enabled on the main
-requests (and not on the subrequests).
+This option adds some randomness to the delay. It's useful to avoid sending
+multiple requests to the server at the exact same time. The randomness is
+calculated as ``delay * jitter``. For example: if delay is ``1000ms`` and jitter
+is ``0.2``, the actual delay will be a number between ``800`` and ``1200`` (1000 +/- 20%).
 
-.. _profiler-dsn:
+local_cert
+..........
 
-dsn
-...
+**type**: ``string``
 
-**type**: ``string`` **default**: ``file:%kernel.cache_dir%/profiler``
+The path to a file that contains the `PEM formatted`_ certificate used by the
+HTTP client. This is often combined with the ``local_pk`` and ``passphrase``
+options.
 
-The DSN where to store the profiling information.
+local_pk
+........
 
-.. _collect_serializer_data:
+**type**: ``string``
 
-collect_serializer_data
-.......................
+The path of a file that contains the `PEM formatted`_ private key of the
+certificate defined in the ``local_cert`` option.
 
-**type**: ``boolean`` **default**: ``false``
+.. _reference-http-client-retry-max-delay:
 
-Set this option to ``true`` to enable the serializer data collector and its
-profiler panel. When this option is ``true``, all normalizers and encoders are
-decorated by traceable implementations that collect profiling information about them.
+max_delay
+.........
 
-rate_limiter
-~~~~~~~~~~~~
+**type**: ``integer`` **default**: ``0``
 
-.. _reference-rate-limiter-name:
+The maximum amount of milliseconds initial to wait between retries.
+Use ``0`` to not limit the duration.
 
-name
-....
+max_duration
+............
 
-**type**: ``prototype``
+**type**: ``float`` **default**: ``0``
 
-Name of the rate limiter you want to create.
+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.
 
-lock_factory
-""""""""""""
+max_host_connections
+....................
 
-**type**: ``string`` **default:** ``lock.factory``
+**type**: ``integer`` **default**: ``6``
 
-The service that is used to create a lock. The service has to be an instance of
-the :class:`Symfony\\Component\\Lock\\LockFactory` class.
+Defines the maximum amount of simultaneously open connections to a single host
+(considering a "host" the same as a "host name + port number" pair). This limit
+also applies for proxy connections, where the proxy is considered to be the host
+for which this limit is applied.
 
-policy
-""""""
+max_redirects
+.............
 
-**type**: ``string`` **required**
+**type**: ``integer`` **default**: ``20``
 
-The name of the rate limiting algorithm to use. Example names are ``fixed_window``,
-``sliding_window`` and ``no_limit``. See :ref:`Rate Limiter Policies <rate-limiter-policies>`)
-for more information.
+The maximum number of redirects to follow. Use ``0`` to not follow any
+redirection.
 
-request
-~~~~~~~
+.. _reference-http-client-retry-max-retries:
 
-formats
-.......
+max_retries
+...........
 
-**type**: ``array`` **default**: ``[]``
+**type**: ``integer`` **default**: ``3``
 
-This setting is used to associate additional request formats (e.g. ``html``)
-to one or more mime types (e.g. ``text/html``), which will allow you to use the
-format & mime types to call
-:method:`Request::getFormat($mimeType) <Symfony\\Component\\HttpFoundation\\Request::getFormat>` or
-:method:`Request::getMimeType($format) <Symfony\\Component\\HttpFoundation\\Request::getMimeType>`.
+The maximum number of retries for failing requests. When the maximum is reached,
+the client returns the last received response.
 
-In practice, this is important because Symfony uses it to automatically set the
-``Content-Type`` header on the ``Response`` (if you don't explicitly set one).
-If you pass an array of mime types, the first will be used for the header.
+.. _reference-http-client-retry-multiplier:
 
-To configure a ``jsonp`` format:
+multiplier
+..........
 
-.. configuration-block::
+**type**: ``float`` **default**: ``2``
 
-    .. code-block:: yaml
+This value is multiplied to the delay each time a retry occurs, to distribute
+retries in time instead of making all of them sequentially.
 
-        # config/packages/framework.yaml
-        framework:
-            request:
-                formats:
-                    jsonp: 'application/javascript'
+no_proxy
+........
 
-    .. code-block:: xml
+**type**: ``string`` | ``null`` **default**: ``null``
 
-        <!-- config/packages/framework.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
+A comma separated list of hosts that do not require a proxy to be reached, even
+if one is configured. Use the ``'*'`` wildcard to match all hosts and an empty
+string to match none (disables the proxy).
 
-        <container xmlns="http://symfony.com/schema/dic/services"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xmlns:framework="http://symfony.com/schema/dic/symfony"
-            xsi:schemaLocation="http://symfony.com/schema/dic/services
-                https://symfony.com/schema/dic/services/services-1.0.xsd
-                http://symfony.com/schema/dic/symfony
-                https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+passphrase
+..........
 
-            <framework:config>
-                <framework:request>
-                    <framework:format name="jsonp">
-                        <framework:mime-type>application/javascript</framework:mime-type>
-                    </framework:format>
-                </framework:request>
-            </framework:config>
-        </container>
+**type**: ``string``
 
-    .. code-block:: php
+The passphrase used to encrypt the certificate stored in the file defined in the
+``local_cert`` option.
 
-        // config/packages/framework.php
-        use Symfony\Config\FrameworkConfig;
+peer_fingerprint
+................
 
-        return static function (FrameworkConfig $framework): void {
-            $framework->request()
-                ->format('jsonp', 'application/javascript');
-        };
+**type**: ``array``
 
-router
-~~~~~~
+When negotiating a TLS connection, the server sends a certificate
+indicating its identity. A public key is extracted from this certificate and if
+it does not exactly match any of the public keys provided in this option, the
+connection is aborted before sending or receiving any data.
 
-resource
-........
+The value of this option is an associative array of ``algorithm => hash``
+(e.g ``['pin-sha256' => '...']``).
 
-**type**: ``string`` **required**
+proxy
+.....
 
-The path the main routing resource (e.g. a YAML file) that contains the
-routes and imports the router should load.
+**type**: ``string`` | ``null``
 
-.. _reference-router-type:
+The HTTP proxy to use to make the requests. Leave it to ``null`` to detect the
+proxy automatically based on your system configuration.
 
-type
-....
+query
+.....
 
-**type**: ``string``
+**type**: ``array``
 
-The type of the resource to hint the loaders about the format. This isn't
-needed when you use the default routers with the expected file extensions
-(``.xml``, ``.yaml``, ``.php``).
+An associative array of the query string values added to the URL before making
+the request. This value must use the format ``['parameter-name' => parameter-value, ...]``.
 
-default_uri
-...........
+rate_limiter
+............
 
 **type**: ``string``
 
-The default URI used to generate URLs in a non-HTTP context (see
-:ref:`Generating URLs in Commands <router-generate-urls-commands>`).
+The service ID of the rate limiter used to limit the number of HTTP requests
+within a certain period. The service must implement the
+:class:`Symfony\\Component\\RateLimiter\\LimiterInterface`.
 
-http_port
-.........
+.. versionadded:: 7.1
 
-**type**: ``integer`` **default**: ``80``
+    The ``rate_limiter`` option was introduced in Symfony 7.1.
 
-The port for normal http requests (this is used when matching the scheme).
+resolve
+.......
 
-https_port
-..........
+**type**: ``array``
 
-**type**: ``integer`` **default**: ``443``
+A list of hostnames and their IP addresses to pre-populate the DNS cache used by
+the HTTP client in order to avoid a DNS lookup for those hosts. This option is
+useful to improve security when IPs are checked before the URL is passed to the
+client and to make your tests easier.
 
-The port for https requests (this is used when matching the scheme).
+The value of this option is an associative array of ``domain => IP address``
+(e.g ``['symfony.com' => '46.137.106.254', ...]``).
 
-strict_requirements
-...................
+.. _reference-http-client-retry-failed:
 
-**type**: ``mixed`` **default**: ``true``
+retry_failed
+............
 
-Determines the routing generator behavior. When generating a route that
-has specific :ref:`parameter requirements <routing-requirements>`, the generator
-can behave differently in case the used parameters do not meet these requirements.
+**type**: ``array``
 
-The value can be one of:
+This option configures the behavior of the HTTP client when some request fails,
+including which types of requests to retry and how many times. The behavior is
+defined with the following options:
 
-``true``
-    Throw an exception when the requirements are not met;
-``false``
-    Disable exceptions when the requirements are not met and return ``''``
-    instead;
-``null``
-    Disable checking the requirements (thus, match the route even when the
-    requirements don't match).
+* :ref:`delay <reference-http-client-retry-delay>`
+* :ref:`http_codes <reference-http-client-retry-http-codes>`
+* :ref:`jitter <reference-http-client-retry-jitter>`
+* :ref:`max_delay <reference-http-client-retry-max-delay>`
+* :ref:`max_retries <reference-http-client-retry-max-retries>`
+* :ref:`multiplier <reference-http-client-retry-multiplier>`
 
-``true`` is recommended in the development environment, while ``false``
-or ``null`` might be preferred in production.
+.. code-block:: yaml
 
-utf8
-....
+    # config/packages/framework.yaml
+    framework:
+        # ...
+        http_client:
+            # ...
+            default_options:
+                retry_failed:
+                    # retry_strategy: app.custom_strategy
+                    http_codes:
+                        0: ['GET', 'HEAD']   # retry network errors if request method is GET or HEAD
+                        429: true            # retry all responses with 429 status code
+                        500: ['GET', 'HEAD']
+                    max_retries: 2
+                    delay: 1000
+                    multiplier: 3
+                    max_delay: 5000
+                    jitter: 0.3
+
+            scoped_clients:
+                my_api.client:
+                    # ...
+                    retry_failed:
+                        max_retries: 4
 
-**type**: ``boolean`` **default**: ``true``
+retry_strategy
+..............
 
-When this option is set to ``true``, the regular expressions used in the
-:ref:`requirements of route parameters <routing-requirements>` will be run
-using the `utf-8 modifier`_. This will for example match any UTF-8 character
-when using ``.``, instead of matching only a single byte.
+**type**: ``string``
 
-If the charset of your application is UTF-8 (as defined in the
-:ref:`getCharset() method <configuration-kernel-charset>` of your kernel) it's
-recommended setting it to ``true``. This will make non-UTF8 URLs to generate 404
-errors.
+The service is used to decide if a request should be retried and to compute the
+time to wait between retries. By default, it uses an instance of
+:class:`Symfony\\Component\\HttpClient\\Retry\\GenericRetryStrategy` configured
+with ``http_codes``, ``delay``, ``max_delay``, ``multiplier`` and ``jitter``
+options. This class has to implement
+:class:`Symfony\\Component\\HttpClient\\Retry\\RetryStrategyInterface`.
 
-cache_dir
-.........
+scope
+.....
 
-**type**: ``string`` **default**: ``%kernel.cache_dir%``
+**type**: ``string``
 
-The directory where routing information will be cached. Can be set to
-``~`` (``null``) to disable route caching.
+For scoped clients only: the regular expression that the URL must match before
+applying all other non-default options. By default, the scope is derived from
+`base_uri`_.
 
-.. deprecated:: 7.1
+timeout
+.......
 
-    Setting the ``cache_dir`` option is deprecated since Symfony 7.1. The routes
-    are now always cached in the ``%kernel.build_dir%`` directory.
+**type**: ``float`` **default**: depends on your PHP config
 
-secrets
-~~~~~~~
+Time, in seconds, to wait for network activity. If the connection is idle for longer, a
+:class:`Symfony\\Component\\HttpClient\\Exception\\TransportException` is thrown.
+Its default value is the same as the value of PHP's `default_socket_timeout`_
+config option.
 
-enabled
-.......
+verify_host
+...........
 
 **type**: ``boolean`` **default**: ``true``
 
-Whether to enable or not secrets managements.
-
-decryption_env_var
-..................
+If ``true``, the certificate sent by other servers is verified to ensure that
+their common name matches the host included in the URL. This is usually
+combined with ``verify_peer`` to also verify the certificate authenticity.
 
-**type**: ``string`` **default**: ``base64:default::SYMFONY_DECRYPTION_SECRET``
+verify_peer
+...........
 
-The env var name that contains the vault decryption secret. By default, this
-value will be decoded from base64.
+**type**: ``boolean`` **default**: ``true``
 
-local_dotenv_file
-.................
+If ``true``, the certificate sent by other servers when negotiating a TLS
+connection is verified for authenticity. Authenticating the certificate is not
+enough to be sure about the server, so you should combine this with the
+``verify_host`` option.
 
-**type**: ``string`` **default**: ``%kernel.project_dir%/.env.%kernel.environment%.local``
+ .. _configuration-framework-http_method_override:
 
-The path to the local ``.env`` file. This file must contain the vault
-decryption key, given by the ``decryption_env_var`` option.
+http_method_override
+~~~~~~~~~~~~~~~~~~~~
 
-vault_directory
-...............
+**type**: ``boolean`` **default**: ``false``
 
-**type**: ``string`` **default**: ``%kernel.project_dir%/config/secrets/%kernel.runtime_environment%``
+This determines whether the ``_method`` request parameter is used as the
+intended HTTP method on POST requests. If enabled, the
+:method:`Request::enableHttpMethodParameterOverride <Symfony\\Component\\HttpFoundation\\Request::enableHttpMethodParameterOverride>`
+method gets called automatically. It becomes the service container parameter
+named ``kernel.http_method_override``.
 
-The directory to store the secret vault. By default, the path includes the value
-of the :ref:`kernel.runtime_environment <configuration-kernel-runtime-environment>`
-parameter.
+.. seealso::
 
-.. _config-framework-session:
+    :ref:`Changing the Action and HTTP Method <forms-change-action-method>` of
+    Symfony forms.
 
-session
-~~~~~~~
+.. warning::
 
-.. _storage_id:
+    If you're using the :ref:`HttpCache Reverse Proxy <symfony2-reverse-proxy>`
+    with this option, the kernel will ignore the ``_method`` parameter,
+    which could lead to errors.
 
-storage_factory_id
-..................
+    To fix this, invoke the ``enableHttpMethodParameterOverride()`` method
+    before creating the ``Request`` object::
 
-**type**: ``string`` **default**: ``session.storage.factory.native``
+        // public/index.php
 
-The service ID used for creating the ``SessionStorageInterface`` that stores
-the session. This service is available in the Symfony application via the
-``session.storage.factory`` service alias. The class has to implement
-:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageFactoryInterface`.
-To see a list of all available storages, run:
+        // ...
+        $kernel = new CacheKernel($kernel);
 
-.. code-block:: terminal
+        Request::enableHttpMethodParameterOverride(); // <-- add this line
+        $request = Request::createFromGlobals();
+        // ...
 
-    $ php bin/console debug:container session.storage.factory.
+ide
+~~~
 
-.. _config-framework-session-handler-id:
+**type**: ``string`` **default**: ``%env(default::SYMFONY_IDE)%``
 
-handler_id
-..........
+Symfony turns file paths seen in variable dumps and exception messages into
+links that open those files right inside your browser. If you prefer to open
+those files in your favorite IDE or text editor, set this option to any of the
+following values: ``phpstorm``, ``sublime``, ``textmate``, ``macvim``, ``emacs``,
+``atom`` and ``vscode``.
 
-**type**: ``string`` | ``null`` **default**: ``null``
+.. note::
 
-If ``framework.session.save_path`` is not set, the default value of this option
-is ``null``, which means to use the session handler configured in php.ini. If the
-``framework.session.save_path`` option is set, then Symfony stores sessions using
-the native file session handler.
+    The ``phpstorm`` option is supported natively by PhpStorm on macOS and
+    Windows; Linux requires installing `phpstorm-url-handler`_.
 
-It is possible to :ref:`store sessions in a database <session-database>`,
-and also to configure the session handler with a DSN:
+If you use another editor, the expected configuration value is a URL template
+that contains an ``%f`` placeholder where the file path is expected and ``%l``
+placeholder for the line number (percentage signs (``%``) must be escaped by
+doubling them to prevent Symfony from interpreting them as container parameters).
 
 .. configuration-block::
 
@@ -1639,12 +1947,7 @@ and also to configure the session handler with a DSN:
 
         # config/packages/framework.yaml
         framework:
-            session:
-                # a few possible examples
-                handler_id: 'redis://localhost'
-                handler_id: '%env(REDIS_URL)%'
-                handler_id: '%env(DATABASE_URL)%'
-                handler_id: 'file://%kernel.project_dir%/var/sessions'
+            ide: 'myide://open?url=file://%%f&line=%%l'
 
     .. code-block:: xml
 
@@ -1656,268 +1959,290 @@ and also to configure the session handler with a DSN:
             xsi:schemaLocation="http://symfony.com/schema/dic/services
                 https://symfony.com/schema/dic/services/services-1.0.xsd
                 http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
-            <framework:config>
-                <!-- a few possible examples -->
-                <framework:session enabled="true"
-                    handler-id="redis://localhost"
-                    handler-id="%env(REDIS_URL)%"
-                    handler-id="%env(DATABASE_URL)%"
-                    handler-id="file://%kernel.project_dir%/var/sessions"/>
-            </framework:config>
+
+            <framework:config ide="myide://open?url=file://%%f&line=%%l"/>
         </container>
 
     .. code-block:: php
 
         // config/packages/framework.php
-        use function Symfony\Component\DependencyInjection\Loader\Configurator\env;
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
-            // ...
-
-            $framework->session()
-                // a few possible examples
-                ->handlerId('redis://localhost')
-                ->handlerId(env('REDIS_URL'))
-                ->handlerId(env('DATABASE_URL'))
-                ->handlerId('file://%kernel.project_dir%/var/sessions');
+            $framework->ide('myide://open?url=file://%%f&line=%%l');
         };
 
+Since every developer uses a different IDE, the recommended way to enable this
+feature is to configure it on a system level. First, you can define this option
+in the ``SYMFONY_IDE`` environment variable, which Symfony reads automatically
+when ``framework.ide`` config is not set.
+
+Another alternative is to set the ``xdebug.file_link_format`` option in your
+``php.ini`` configuration file. The format to use is the same as for the
+``framework.ide`` option, but without the need to escape the percent signs
+(``%``) by doubling them:
+
+.. code-block:: ini
+
+    // example for PhpStorm
+    xdebug.file_link_format="phpstorm://open?file=%f&line=%l"
+
+    // example for PhpStorm with Jetbrains Toolbox
+    xdebug.file_link_format="jetbrains://phpstorm/navigate/reference?project=example&path=%f:%l"
+
+    // example for Sublime Text
+    xdebug.file_link_format="subl://open?url=file://%f&line=%l"
+
 .. note::
 
-    Supported DSN protocols are the following:
+    If both ``framework.ide`` and ``xdebug.file_link_format`` are defined,
+    Symfony uses the value of the ``xdebug.file_link_format`` option.
 
-    * ``file``
-    * ``redis``
-    * ``rediss`` (Redis over TLS)
-    * ``memcached`` (requires :doc:`symfony/cache </components/cache>`)
-    * ``pdo_oci`` (requires :doc:`doctrine/dbal </doctrine/dbal>`)
-    * ``mssql``
-    * ``mysql``
-    * ``mysql2``
-    * ``pgsql``
-    * ``postgres``
-    * ``postgresql``
-    * ``sqlsrv``
-    * ``sqlite``
-    * ``sqlite3``
+.. tip::
 
-.. _name:
+    Setting the ``xdebug.file_link_format`` ini option works even if the Xdebug
+    extension is not enabled.
 
-name
-....
+.. tip::
 
-**type**: ``string``
+    When running your app in a container or in a virtual machine, you can tell
+    Symfony to map files from the guest to the host by changing their prefix.
+    This map should be specified at the end of the URL template, using ``&`` and
+    ``>`` as guest-to-host separators:
 
-This specifies the name of the session cookie.
+    .. code-block:: text
 
-If not set, ``php.ini``'s `session.name`_ directive will be relied on.
+        // /path/to/guest/.../file will be opened
+        // as /path/to/host/.../file on the host
+        // and /var/www/app/ as /projects/my_project/ also
+        'myide://%%f:%%l&/path/to/guest/>/path/to/host/&/var/www/app/>/projects/my_project/&...'
 
-cookie_lifetime
-...............
+        // example for PhpStorm
+        'phpstorm://open?file=%%f&line=%%l&/var/www/app/>/projects/my_project/'
 
-**type**: ``integer``
+.. _reference-lock:
 
-This determines the lifetime of the session - in seconds.
-Setting this value to ``0`` means the cookie is valid for
-the length of the browser session.
+lock
+~~~~
 
-If not set, ``php.ini``'s `session.cookie_lifetime`_ directive will be relied on.
+**type**: ``string`` | ``array``
 
-cookie_path
-...........
+The default lock adapter. If not defined, the value is set to ``semaphore`` when
+available, or to ``flock`` otherwise. Store's DSN are also allowed.
 
-**type**: ``string``
+.. _reference-lock-enabled:
 
-This determines the path to set in the session cookie.
+enabled
+.......
 
-If not set, ``php.ini``'s `session.cookie_path`_ directive will be relied on.
+**type**: ``boolean`` **default**: ``true``
 
-cache_limiter
-.............
+Whether to enable the support for lock or not. This setting is
+automatically set to ``true`` when one of the child settings is configured.
 
-**type**: ``string`` **default**: ``0``
+.. _reference-lock-resources:
+
+resources
+.........
 
-If set to ``0``, Symfony won't set any particular header related to the cache
-and it will rely on ``php.ini``'s `session.cache_limiter`_ directive.
+**type**: ``array``
 
-Unlike the other session options, ``cache_limiter`` is set as a regular
-:ref:`container parameter <configuration-parameters>`:
+A map of lock stores to be created by the framework extension, with
+the name as key and DSN as value:
 
 .. configuration-block::
 
     .. code-block:: yaml
 
-        # config/services.yaml
-        parameters:
-            session.storage.options:
-                cache_limiter: 0
+        # config/packages/lock.yaml
+        framework:
+            lock: '%env(LOCK_DSN)%'
 
     .. code-block:: xml
 
-        <!-- config/services.xml -->
+        <!-- config/packages/lock.xml -->
         <?xml version="1.0" encoding="UTF-8" ?>
         <container xmlns="http://symfony.com/schema/dic/services"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
             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/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
-            <parameters>
-                <parameter key="session.storage.options" type="collection">
-                    <parameter key="cache_limiter">0</parameter>
-                </parameter>
-            </parameters>
+            <framework:config>
+                <framework:lock>
+                    <framework:resource name="default">%env(LOCK_DSN)%</framework:resource>
+                </framework:lock>
+            </framework:config>
         </container>
 
     .. code-block:: php
 
-        // config/services.php
-        $container->setParameter('session.storage.options', [
-            'cache_limiter' => 0,
-        ]);
+        // config/packages/lock.php
+        use Symfony\Config\FrameworkConfig;
 
-Be aware that if you configure it, you'll have to set other session-related options
-as parameters as well.
+        return static function (FrameworkConfig $framework): void {
+            $framework->lock()
+                ->resource('default', [env('LOCK_DSN')]);
+        };
 
-cookie_domain
-.............
+.. seealso::
 
-**type**: ``string``
+    For more details, see :doc:`/lock`.
 
-This determines the domain to set in the session cookie.
+.. _reference-lock-resources-name:
 
-If not set, ``php.ini``'s `session.cookie_domain`_ directive will be relied on.
+name
+""""
 
-cookie_samesite
-...............
+**type**: ``prototype``
 
-**type**: ``string`` or ``null`` **default**: ``null``
+Name of the lock you want to create.
 
-It controls the way cookies are sent when the HTTP request did not originate
-from the same domain that is associated with the cookies. Setting this option is
-recommended to mitigate `CSRF security attacks`_.
+mailer
+~~~~~~
 
-By default, browsers send all cookies related to the domain of the HTTP request.
-This may be a problem for example when you visit a forum and some malicious
-comment includes a link like ``https://some-bank.com/?send_money_to=attacker&amount=1000``.
-If you were previously logged into your bank website, the browser will send all
-those cookies when making that HTTP request.
+.. _mailer-dsn:
 
-The possible values for this option are:
+dsn
+...
 
-* ``null``, use ``php.ini``'s `session.cookie_samesite`_ directive.
-* ``'none'`` (or the ``Symfony\Component\HttpFoundation\Cookie::SAMESITE_NONE`` constant), use it to allow
-  sending of cookies when the HTTP request originated from a different domain
-  (previously this was the default behavior of null, but in newer browsers ``'lax'``
-  would be applied when the header has not been set)
-* ``'strict'`` (or the ``Cookie::SAMESITE_STRICT`` constant), use it to never
-  send any cookie when the HTTP request did not originate from the same domain.
-* ``'lax'`` (or the ``Cookie::SAMESITE_LAX`` constant), use it to allow sending
-  cookies when the request originated from a different domain, but only when the
-  user consciously made the request (by clicking a link or submitting a form
-  with the ``GET`` method).
+**type**: ``string`` **default**: ``null``
 
-cookie_secure
-.............
+The DSN used by the mailer. When several DSN may be used, use
+``transports`` option (see below) instead.
 
-**type**: ``boolean`` or ``'auto'``
+envelope
+........
 
-This determines whether cookies should only be sent over secure connections. In
-addition to ``true`` and ``false``, there's a special ``'auto'`` value that
-means ``true`` for HTTPS requests and ``false`` for HTTP requests.
+recipients
+""""""""""
 
-If not set, ``php.ini``'s `session.cookie_secure`_ directive will be relied on.
+**type**: ``array``
 
-cookie_httponly
-...............
+The "envelope recipient" which is used as the value of ``RCPT TO`` during the
+the `SMTP session`_. This value overrides any other recipient set in the code.
 
-**type**: ``boolean`` **default**: ``true``
+.. configuration-block::
 
-This determines whether cookies should only be accessible through the HTTP
-protocol. This means that the cookie won't be accessible by scripting
-languages, such as JavaScript. This setting can effectively help to reduce
-identity theft through :ref:`XSS attacks <xss-attacks>`.
+    .. code-block:: yaml
 
-gc_divisor
-..........
+        # config/packages/mailer.yaml
+        framework:
+            mailer:
+                dsn: 'smtp://localhost:25'
+                envelope:
+                    recipients: ['admin@symfony.com', 'lead@symfony.com']
 
-**type**: ``integer``
+    .. code-block:: xml
 
-See `gc_probability`_.
+        <!-- config/packages/mailer.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+            <framework:config>
+                <framework:mailer dsn="smtp://localhost:25">
+                    <framework:envelope>
+                        <framework:recipient>admin@symfony.com</framework:recipient>
+                        <framework:recipient>lead@symfony.com</framework:recipient>
+                    </framework:envelope>
+                </framework:mailer>
+            </framework:config>
+        </container>
 
-If not set, ``php.ini``'s `session.gc_divisor`_ directive will be relied on.
+    .. code-block:: php
 
-gc_probability
-..............
+        // config/packages/mailer.php
+        namespace Symfony\Component\DependencyInjection\Loader\Configurator;
 
-**type**: ``integer``
+        return static function (ContainerConfigurator $container): void {
+            $container->extension('framework', [
+                'mailer' => [
+                    'dsn' => 'smtp://localhost:25',
+                    'envelope' => [
+                        'recipients' => [
+                            'admin@symfony.com',
+                            'lead@symfony.com',
+                        ],
+                    ],
+                ],
+            ]);
+        };
 
-This defines the probability that the garbage collector (GC) process is
-started on every session initialization. The probability is calculated by
-using ``gc_probability`` / ``gc_divisor``, e.g. 1/100 means there is a 1%
-chance that the GC process will start on each request.
+sender
+""""""
 
-If not set, Symfony will use the value of the `session.gc_probability`_ directive
-in the ``php.ini`` configuration file.
+**type**: ``string``
 
-.. versionadded:: 7.2
+The "envelope sender" which is used as the value of ``MAIL FROM`` during the
+`SMTP session`_. This value overrides any other sender set in the code.
 
-    Relying on ``php.ini``'s directive as default for ``gc_probability`` was
-    introduced in Symfony 7.2.
+.. _mailer-headers:
 
-gc_maxlifetime
-..............
+headers
+.......
 
-**type**: ``integer``
+**type**: ``array``
 
-This determines the number of seconds after which data will be seen as "garbage"
-and potentially cleaned up. Garbage collection may occur during session
-start and depends on `gc_divisor`_ and `gc_probability`_.
+Headers to add to emails. The key (``name`` attribute in xml format) is the
+header name and value the header value.
 
-If not set, ``php.ini``'s `session.gc_maxlifetime`_ directive will be relied on.
+.. seealso::
 
-sid_length
-..........
+    For more information, see :ref:`Configuring Emails Globally <mailer-configure-email-globally>`
 
-**type**: ``integer``
+message_bus
+...........
 
-This determines the length of session ID string, which can be an integer between
-``22`` and ``256`` (both inclusive), ``32`` being the recommended value. Longer
-session IDs are harder to guess.
+**type**: ``string`` **default**: ``null`` or default bus if Messenger component is installed
 
-If not set, ``php.ini``'s `session.sid_length`_ directive will be relied on.
+Service identifier of the message bus to use when using the
+:doc:`Messenger component </messenger>` (e.g. ``messenger.default_bus``).
 
-.. deprecated:: 7.2
+transports
+..........
 
-    The ``sid_length`` option was deprecated in Symfony 7.2. No alternative is
-    provided as PHP 8.4 has deprecated the related option.
+**type**: ``array``
 
-sid_bits_per_character
-......................
+A :ref:`list of DSN <multiple-email-transports>` that can be used by the
+mailer. A transport name is the key and the dsn is the value.
 
-**type**: ``integer``
+messenger
+~~~~~~~~~
 
-This determines the number of bits in the encoded session ID character. The possible
-values are ``4`` (0-9, a-f), ``5`` (0-9, a-v), and ``6`` (0-9, a-z, A-Z, "-", ",").
-The more bits results in stronger session ID. ``5`` is recommended value for
-most environments.
+enabled
+.......
 
-If not set, ``php.ini``'s `session.sid_bits_per_character`_ directive will be relied on.
+**type**: ``boolean`` **default**: ``true``
 
-.. deprecated:: 7.2
+Whether to enable or not Messenger.
 
-    The ``sid_bits_per_character`` option was deprecated in Symfony 7.2. No alternative
-    is provided as PHP 8.4 has deprecated the related option.
+.. seealso::
 
-save_path
-.........
+    For more details, see the :doc:`Messenger component </messenger>`
+    documentation.
 
-**type**: ``string`` | ``null`` **default**: ``%kernel.cache_dir%/sessions``
+php_errors
+~~~~~~~~~~
 
-This determines the argument to be passed to the save handler. If you choose
-the default file handler, this is the path where the session files are created.
+log
+...
 
-If ``null``, ``php.ini``'s `session.save_path`_ directive will be relied on:
+**type**: ``boolean`` | ``int`` | ``array<int, string>`` **default**: ``true``
+
+Use the application logger instead of the PHP logger for logging PHP errors.
+When an integer value is used, it defines a bitmask of PHP errors that will
+be logged. Those integer values must be the same used in the
+`error_reporting PHP option`_. The default log levels will be used for each
+PHP error.
+When a boolean value is used, ``true`` enables logging for all PHP errors
+while ``false`` disables logging entirely.
+
+This option also accepts a map of PHP errors to log levels:
 
 .. configuration-block::
 
@@ -1925,8 +2250,23 @@ If ``null``, ``php.ini``'s `session.save_path`_ directive will be relied on:
 
         # config/packages/framework.yaml
         framework:
-            session:
-                save_path: ~
+            php_errors:
+                log:
+                    !php/const \E_DEPRECATED: !php/const Psr\Log\LogLevel::ERROR
+                    !php/const \E_USER_DEPRECATED: !php/const Psr\Log\LogLevel::ERROR
+                    !php/const \E_NOTICE: !php/const Psr\Log\LogLevel::ERROR
+                    !php/const \E_USER_NOTICE: !php/const Psr\Log\LogLevel::ERROR
+                    !php/const \E_STRICT: !php/const Psr\Log\LogLevel::ERROR
+                    !php/const \E_WARNING: !php/const Psr\Log\LogLevel::ERROR
+                    !php/const \E_USER_WARNING: !php/const Psr\Log\LogLevel::ERROR
+                    !php/const \E_COMPILE_WARNING: !php/const Psr\Log\LogLevel::ERROR
+                    !php/const \E_CORE_WARNING: !php/const Psr\Log\LogLevel::ERROR
+                    !php/const \E_USER_ERROR: !php/const Psr\Log\LogLevel::CRITICAL
+                    !php/const \E_RECOVERABLE_ERROR: !php/const Psr\Log\LogLevel::CRITICAL
+                    !php/const \E_COMPILE_ERROR: !php/const Psr\Log\LogLevel::CRITICAL
+                    !php/const \E_PARSE: !php/const Psr\Log\LogLevel::CRITICAL
+                    !php/const \E_ERROR: !php/const Psr\Log\LogLevel::CRITICAL
+                    !php/const \E_CORE_ERROR: !php/const Psr\Log\LogLevel::CRITICAL
 
     .. code-block:: xml
 
@@ -1940,282 +2280,225 @@ If ``null``, ``php.ini``'s `session.save_path`_ directive will be relied on:
                 http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
             <framework:config>
-                <framework:session save-path="null"/>
+                <!-- in XML configuration you cannot use PHP constants as the value of
+                     the 'type' attribute, which makes this format way less readable.
+                     Consider using YAML or PHP for this configuration -->
+                <framework:log type="8" logLevel="error"/>
+                <framework:log type="2" logLevel="error"/>
+                <!-- ... -->
             </framework:config>
         </container>
 
     .. code-block:: php
 
         // config/packages/framework.php
+        use Psr\Log\LogLevel;
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
-            $framework->session()
-                ->savePath(null);
+            $framework->phpErrors()->log(\E_DEPRECATED, LogLevel::ERROR);
+            $framework->phpErrors()->log(\E_USER_DEPRECATED, LogLevel::ERROR);
+            // ...
         };
 
-.. _reference-session-metadata-update-threshold:
-
-metadata_update_threshold
-.........................
+throw
+.....
 
-**type**: ``integer`` **default**: ``0``
+**type**: ``boolean`` **default**: ``%kernel.debug%``
 
-This is how many seconds to wait between updating/writing the session metadata.
-This can be useful if, for some reason, you want to limit the frequency at which
-the session persists, instead of doing that on every request.
+Throw PHP errors as ``\ErrorException`` instances. The parameter
+``debug.error_handler.throw_at`` controls the threshold.
 
-.. _reference-session-enabled:
+profiler
+~~~~~~~~
 
-enabled
+collect
 .......
 
 **type**: ``boolean`` **default**: ``true``
 
-Whether to enable the session support in the framework.
+This option configures the way the profiler behaves when it is enabled. If set
+to ``true``, the profiler collects data for all requests. If you want to only
+collect information on-demand, you can set the ``collect`` flag to ``false`` and
+activate the data collectors manually::
 
-.. configuration-block::
+    $profiler->enable();
 
-    .. code-block:: yaml
+collect_parameter
+.................
 
-        # config/packages/framework.yaml
-        framework:
-            session:
-                enabled: true
+**type**: ``string`` **default**: ``null``
 
-    .. code-block:: xml
+This specifies name of a query parameter, a body parameter or a request attribute
+used to enable or disable collection of data by the profiler for each request.
+Combine it with the ``collect`` option to enable/disable the profiler on demand:
 
-        <!-- config/packages/framework.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <container xmlns="http://symfony.com/schema/dic/services"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xmlns:framework="http://symfony.com/schema/dic/symfony"
-            xsi:schemaLocation="http://symfony.com/schema/dic/services
-                https://symfony.com/schema/dic/services/services-1.0.xsd
-                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+* If the ``collect`` option is set to ``true`` but this parameter exists in a
+  request and has any value other than ``true``, ``yes``, ``on`` or ``1``, the
+  request data will not be collected;
+* If the ``collect`` option is set to ``false``, but this parameter exists in a
+  request and has value of ``true``, ``yes``, ``on`` or ``1``, the request data
+  will be collected.
 
-            <framework:config>
-                <framework:session enabled="true"/>
-            </framework:config>
-        </container>
+.. _collect_serializer_data:
 
-    .. code-block:: php
+collect_serializer_data
+.......................
 
-        // config/packages/framework.php
-        use Symfony\Config\FrameworkConfig;
+**type**: ``boolean`` **default**: ``false``
 
-        return static function (FrameworkConfig $framework): void {
-            $framework->session()
-                ->enabled(true);
-        };
+Set this option to ``true`` to enable the serializer data collector and its
+profiler panel. When this option is ``true``, all normalizers and encoders are
+decorated by traceable implementations that collect profiling information about them.
 
-use_cookies
-...........
+.. _profiler-dsn:
 
-**type**: ``boolean``
+dsn
+...
 
-This specifies if the session ID is stored on the client side using cookies or
-not.
+**type**: ``string`` **default**: ``file:%kernel.cache_dir%/profiler``
 
-If not set, ``php.ini``'s `session.use_cookies`_ directive will be relied on.
+The DSN where to store the profiling information.
 
-ssi
-~~~
+.. _reference-profiler-enabled:
 
 enabled
 .......
 
 **type**: ``boolean`` **default**: ``false``
 
-Whether to enable or not SSI support in your application.
-
-assets
-~~~~~~
-
-.. _reference-assets-base-path:
+The profiler can be enabled by setting this option to ``true``. When you
+install it using Symfony Flex, the profiler is enabled in the ``dev``
+and ``test`` environments.
 
-base_path
-.........
+.. note::
 
-**type**: ``string``
+    The profiler works independently from the Web Developer Toolbar, see
+    the :doc:`WebProfilerBundle configuration </reference/configuration/web_profiler>`
+    on how to disable/enable the toolbar.
 
-This option allows you to define a base path to be used for assets:
+only_exceptions
+...............
 
-.. configuration-block::
+**type**: ``boolean`` **default**: ``false``
 
-    .. code-block:: yaml
+When this is set to ``true``, the profiler will only be enabled when an
+exception is thrown during the handling of the request.
 
-        # config/packages/framework.yaml
-        framework:
-            # ...
-            assets:
-                base_path: '/images'
+.. _only_master_requests:
 
-    .. code-block:: xml
+only_main_requests
+..................
 
-        <!-- config/packages/framework.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <container xmlns="http://symfony.com/schema/dic/services"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xmlns:framework="http://symfony.com/schema/dic/symfony"
-            xsi:schemaLocation="http://symfony.com/schema/dic/services
-                https://symfony.com/schema/dic/services/services-1.0.xsd
-                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+**type**: ``boolean`` **default**: ``false``
 
-            <framework:config>
-                <framework:assets base-path="/images"/>
-            </framework:config>
-        </container>
+When this is set to ``true``, the profiler will only be enabled on the main
+requests (and not on the subrequests).
 
-    .. code-block:: php
+property_access
+~~~~~~~~~~~~~~~
 
-        // config/packages/framework.php
-        use Symfony\Config\FrameworkConfig;
+magic_call
+..........
 
-        return static function (FrameworkConfig $framework): void {
-            // ...
-            $framework->assets()
-                ->basePath('/images');
-        };
+**type**: ``boolean`` **default**: ``false``
 
-.. _reference-templating-base-urls:
-.. _reference-assets-base-urls:
+When enabled, the ``property_accessor`` service uses PHP's
+:ref:`magic __call() method <components-property-access-magic-call>` when
+its ``getValue()`` method is called.
 
-base_urls
+magic_get
 .........
 
-**type**: ``array``
-
-This option allows you to define base URLs to be used for assets.
-If multiple base URLs are provided, Symfony will select one from the
-collection each time it generates an asset's path:
-
-.. configuration-block::
-
-    .. code-block:: yaml
-
-        # config/packages/framework.yaml
-        framework:
-            # ...
-            assets:
-                base_urls:
-                    - 'http://cdn.example.com/'
-
-    .. code-block:: xml
-
-        <!-- config/packages/framework.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <container xmlns="http://symfony.com/schema/dic/services"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xmlns:framework="http://symfony.com/schema/dic/symfony"
-            xsi:schemaLocation="http://symfony.com/schema/dic/services
-                https://symfony.com/schema/dic/services/services-1.0.xsd
-                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
-
-            <framework:config>
-                <framework:assets base-url="http://cdn.example.com/"/>
-            </framework:config>
-        </container>
+**type**: ``boolean`` **default**: ``true``
 
-    .. code-block:: php
+When enabled, the ``property_accessor`` service uses PHP's
+:ref:`magic __get() method <components-property-access-magic-get>` when
+its ``getValue()`` method is called.
 
-        // config/packages/framework.php
-        use Symfony\Config\FrameworkConfig;
+magic_set
+.........
 
-        return static function (FrameworkConfig $framework): void {
-            // ...
-            $framework->assets()
-                ->baseUrls(['http://cdn.example.com/']);
-        };
+**type**: ``boolean`` **default**: ``true``
 
-.. _reference-framework-assets-packages:
+When enabled, the ``property_accessor`` service uses PHP's
+:ref:`magic __set() method <components-property-access-writing-to-objects>` when
+its ``setValue()`` method is called.
 
-packages
-........
+throw_exception_on_invalid_index
+................................
 
-You can group assets into packages, to specify different base URLs for them:
+**type**: ``boolean`` **default**: ``false``
 
-.. configuration-block::
+When enabled, the ``property_accessor`` service throws an exception when you
+try to access an invalid index of an array.
 
-    .. code-block:: yaml
+throw_exception_on_invalid_property_path
+........................................
 
-        # config/packages/framework.yaml
-        framework:
-            # ...
-            assets:
-                packages:
-                    avatars:
-                        base_urls: 'http://static_cdn.example.com/avatars'
+**type**: ``boolean`` **default**: ``true``
 
-    .. code-block:: xml
+When enabled, the ``property_accessor`` service throws an exception when you
+try to access an invalid property path of an object.
 
-        <!-- config/packages/framework.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <container xmlns="http://symfony.com/schema/dic/services"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xmlns:framework="http://symfony.com/schema/dic/symfony"
-            xsi:schemaLocation="http://symfony.com/schema/dic/services
-                https://symfony.com/schema/dic/services/services-1.0.xsd
-                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+property_info
+~~~~~~~~~~~~~
 
-            <framework:config>
-                <framework:assets>
-                    <framework:package
-                        name="avatars"
-                        base-url="http://static_cdn.example.com/avatars"/>
-                </framework:assets>
-            </framework:config>
-        </container>
+.. _reference-property-info-enabled:
 
-    .. code-block:: php
+enabled
+.......
 
-        // config/packages/framework.php
-        use Symfony\Config\FrameworkConfig;
+**type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation
 
-        return static function (FrameworkConfig $framework): void {
-            // ...
-            $framework->assets()
-                ->package('avatars')
-                    ->baseUrls(['http://static_cdn.example.com/avatars']);
-        };
+rate_limiter
+~~~~~~~~~~~~
 
-Now you can use the ``avatars`` package in your templates:
+.. _reference-rate-limiter-name:
 
-.. code-block:: html+twig
+name
+....
 
-    <img src="{{ asset('...', 'avatars') }}">
+**type**: ``prototype``
 
-Each package can configure the following options:
+Name of the rate limiter you want to create.
 
-* :ref:`base_path <reference-assets-base-path>`
-* :ref:`base_urls <reference-assets-base-urls>`
-* :ref:`version_strategy <reference-assets-version-strategy>`
-* :ref:`version <reference-framework-assets-version>`
-* :ref:`version_format <reference-assets-version-format>`
-* :ref:`json_manifest_path <reference-assets-json-manifest-path>`
-* :ref:`strict_mode <reference-assets-strict-mode>`
+lock_factory
+""""""""""""
 
-.. _reference-framework-assets-version:
-.. _ref-framework-assets-version:
+**type**: ``string`` **default:** ``lock.factory``
 
-version
-.......
+The service that is used to create a lock. The service has to be an instance of
+the :class:`Symfony\\Component\\Lock\\LockFactory` class.
 
-**type**: ``string``
+policy
+""""""
 
-This option is used to *bust* the cache on assets by globally adding a query
-parameter to all rendered asset paths (e.g. ``/images/logo.png?v2``). This
-applies only to assets rendered via the Twig ``asset()`` function (or PHP
-equivalent).
+**type**: ``string`` **required**
 
-For example, suppose you have the following:
+The name of the rate limiting algorithm to use. Example names are ``fixed_window``,
+``sliding_window`` and ``no_limit``. See :ref:`Rate Limiter Policies <rate-limiter-policies>`)
+for more information.
 
-.. code-block:: html+twig
+request
+~~~~~~~
 
-    <img src="{{ asset('images/logo.png') }}" alt="Symfony!"/>
+formats
+.......
 
-By default, this will render a path to your image such as ``/images/logo.png``.
-Now, activate the ``version`` option:
+**type**: ``array`` **default**: ``[]``
+
+This setting is used to associate additional request formats (e.g. ``html``)
+to one or more mime types (e.g. ``text/html``), which will allow you to use the
+format & mime types to call
+:method:`Request::getFormat($mimeType) <Symfony\\Component\\HttpFoundation\\Request::getFormat>` or
+:method:`Request::getMimeType($format) <Symfony\\Component\\HttpFoundation\\Request::getMimeType>`.
+
+In practice, this is important because Symfony uses it to automatically set the
+``Content-Type`` header on the ``Response`` (if you don't explicitly set one).
+If you pass an array of mime types, the first will be used for the header.
+
+To configure a ``jsonp`` format:
 
 .. configuration-block::
 
@@ -2223,23 +2506,29 @@ Now, activate the ``version`` option:
 
         # config/packages/framework.yaml
         framework:
-            # ...
-            assets:
-                version: 'v2'
+            request:
+                formats:
+                    jsonp: 'application/javascript'
 
     .. code-block:: xml
 
         <!-- config/packages/framework.xml -->
         <?xml version="1.0" encoding="UTF-8" ?>
+
         <container xmlns="http://symfony.com/schema/dic/services"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:framework="http://symfony.com/schema/dic/symfony"
             xsi:schemaLocation="http://symfony.com/schema/dic/services
                 https://symfony.com/schema/dic/services/services-1.0.xsd
-                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+                http://symfony.com/schema/dic/symfony
+                https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
             <framework:config>
-                <framework:assets version="v2"/>
+                <framework:request>
+                    <framework:format name="jsonp">
+                        <framework:mime-type>application/javascript</framework:mime-type>
+                    </framework:format>
+                </framework:request>
             </framework:config>
         </container>
 
@@ -2249,583 +2538,464 @@ Now, activate the ``version`` option:
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
-            // ...
-            $framework->assets()
-                ->version('v2');
+            $framework->request()
+                ->format('jsonp', 'application/javascript');
         };
 
-Now, the same asset will be rendered as ``/images/logo.png?v2`` If you use
-this feature, you **must** manually increment the ``version`` value
-before each deployment so that the query parameters change.
-
-You can also control how the query string works via the `version_format`_
-option.
-
-.. note::
-
-    This parameter cannot be set at the same time as ``version_strategy`` or ``json_manifest_path``.
-
-.. tip::
-
-    As with all settings, you can use a parameter as value for the
-    ``version``. This makes it easier to increment the cache on each
-    deployment.
-
-.. _reference-templating-version-format:
-.. _reference-assets-version-format:
-
-version_format
-..............
-
-**type**: ``string`` **default**: ``%%s?%%s``
-
-This specifies a :phpfunction:`sprintf` pattern that will be used with the
-`version`_ option to construct an asset's path. By default, the pattern
-adds the asset's version as a query string. For example, if
-``version_format`` is set to ``%%s?version=%%s`` and ``version``
-is set to ``5``, the asset's path would be ``/images/logo.png?version=5``.
-
-.. note::
-
-    All percentage signs (``%``) in the format string must be doubled to
-    escape the character. Without escaping, values might inadvertently be
-    interpreted as :ref:`service-container-parameters`.
+router
+~~~~~~
 
-.. tip::
+cache_dir
+.........
 
-    Some CDN's do not support cache-busting via query strings, so injecting
-    the version into the actual file path is necessary. Thankfully,
-    ``version_format`` is not limited to producing versioned query
-    strings.
+**type**: ``string`` **default**: ``%kernel.cache_dir%``
 
-    The pattern receives the asset's original path and version as its first
-    and second parameters, respectively. Since the asset's path is one
-    parameter, you cannot modify it in-place (e.g. ``/images/logo-v5.png``);
-    however, you can prefix the asset's path using a pattern of
-    ``version-%%2$s/%%1$s``, which would result in the path
-    ``version-5/images/logo.png``.
+The directory where routing information will be cached. Can be set to
+``~`` (``null``) to disable route caching.
 
-    URL rewrite rules could then be used to disregard the version prefix
-    before serving the asset. Alternatively, you could copy assets to the
-    appropriate version path as part of your deployment process and forgot
-    any URL rewriting. The latter option is useful if you would like older
-    asset versions to remain accessible at their original URL.
+.. deprecated:: 7.1
 
-.. _reference-assets-version-strategy:
-.. _reference-templating-version-strategy:
+    Setting the ``cache_dir`` option is deprecated since Symfony 7.1. The routes
+    are now always cached in the ``%kernel.build_dir%`` directory.
 
-version_strategy
-................
+default_uri
+...........
 
-**type**: ``string`` **default**: ``null``
+**type**: ``string``
 
-The service id of the :doc:`asset version strategy </frontend/custom_version_strategy>`
-applied to the assets. This option can be set globally for all assets and
-individually for each asset package:
+The default URI used to generate URLs in a non-HTTP context (see
+:ref:`Generating URLs in Commands <router-generate-urls-commands>`).
 
-.. configuration-block::
+http_port
+.........
 
-    .. code-block:: yaml
+**type**: ``integer`` **default**: ``80``
 
-        # config/packages/framework.yaml
-        framework:
-            assets:
-                # this strategy is applied to every asset (including packages)
-                version_strategy: 'app.asset.my_versioning_strategy'
-                packages:
-                    foo_package:
-                        # this package removes any versioning (its assets won't be versioned)
-                        version: ~
-                    bar_package:
-                        # this package uses its own strategy (the default strategy is ignored)
-                        version_strategy: 'app.asset.another_version_strategy'
-                    baz_package:
-                        # this package inherits the default strategy
-                        base_path: '/images'
+The port for normal http requests (this is used when matching the scheme).
 
-    .. code-block:: xml
+https_port
+..........
 
-        <!-- config/packages/framework.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <container xmlns="http://symfony.com/schema/dic/services"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xmlns:framework="http://symfony.com/schema/dic/symfony"
-            xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
-                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+**type**: ``integer`` **default**: ``443``
 
-            <framework:config>
-                <framework:assets version-strategy="app.asset.my_versioning_strategy">
-                    <!-- this package removes any versioning (its assets won't be versioned) -->
-                    <framework:package
-                        name="foo_package"
-                        version="null"/>
-                    <!-- this package uses its own strategy (the default strategy is ignored) -->
-                    <framework:package
-                        name="bar_package"
-                        version-strategy="app.asset.another_version_strategy"/>
-                    <!-- this package inherits the default strategy -->
-                    <framework:package
-                        name="baz_package"
-                        base_path="/images"/>
-                </framework:assets>
-            </framework:config>
-        </container>
+The port for https requests (this is used when matching the scheme).
 
-    .. code-block:: php
+resource
+........
 
-        // config/packages/framework.php
-        use Symfony\Config\FrameworkConfig;
+**type**: ``string`` **required**
 
-        return static function (FrameworkConfig $framework): void {
-            // ...
-            $framework->assets()
-                ->versionStrategy('app.asset.my_versioning_strategy');
+The path the main routing resource (e.g. a YAML file) that contains the
+routes and imports the router should load.
 
-            $framework->assets()->package('foo_package')
-                // this package removes any versioning (its assets won't be versioned)
-                ->version(null);
+strict_requirements
+...................
 
-            $framework->assets()->package('bar_package')
-                // this package uses its own strategy (the default strategy is ignored)
-                ->versionStrategy('app.asset.another_version_strategy');
+**type**: ``mixed`` **default**: ``true``
 
-            $framework->assets()->package('baz_package')
-                // this package inherits the default strategy
-                ->basePath('/images');
-        };
+Determines the routing generator behavior. When generating a route that
+has specific :ref:`parameter requirements <routing-requirements>`, the generator
+can behave differently in case the used parameters do not meet these requirements.
 
-.. note::
+The value can be one of:
 
-    This parameter cannot be set at the same time as ``version`` or ``json_manifest_path``.
+``true``
+    Throw an exception when the requirements are not met;
+``false``
+    Disable exceptions when the requirements are not met and return ``''``
+    instead;
+``null``
+    Disable checking the requirements (thus, match the route even when the
+    requirements don't match).
 
-.. _reference-assets-json-manifest-path:
-.. _reference-templating-json-manifest-path:
+``true`` is recommended in the development environment, while ``false``
+or ``null`` might be preferred in production.
 
-json_manifest_path
-..................
+.. _reference-router-type:
 
-**type**: ``string`` **default**: ``null``
+type
+....
 
-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.
+**type**: ``string``
 
-.. tip::
+The type of the resource to hint the loaders about the format. This isn't
+needed when you use the default routers with the expected file extensions
+(``.xml``, ``.yaml``, ``.php``).
 
-    Symfony's :ref:`Webpack Encore <frontend-webpack-encore>` supports
-    :ref:`outputting hashed assets <encore-long-term-caching>`. Moreover, this
-    can be incorporated into many other workflows, including Webpack and
-    Gulp using `webpack-manifest-plugin`_ and `gulp-rev`_, respectively.
+utf8
+....
 
-This option can be set globally for all assets and individually for each asset
-package:
+**type**: ``boolean`` **default**: ``true``
 
-.. configuration-block::
+When this option is set to ``true``, the regular expressions used in the
+:ref:`requirements of route parameters <routing-requirements>` will be run
+using the `utf-8 modifier`_. This will for example match any UTF-8 character
+when using ``.``, instead of matching only a single byte.
 
-    .. code-block:: yaml
+If the charset of your application is UTF-8 (as defined in the
+:ref:`getCharset() method <configuration-kernel-charset>` of your kernel) it's
+recommended setting it to ``true``. This will make non-UTF8 URLs to generate 404
+errors.
 
-        # config/packages/framework.yaml
-        framework:
-            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)
-                        json_manifest_path: "%kernel.project_dir%/public/build/a_different_manifest.json"
-                        # Throws an exception when an asset is not found in the manifest
-                        strict_mode: %kernel.debug%
-                    bar_package:
-                        # this package uses the global manifest (the default file is used)
-                        base_path: '/images'
+.. _configuration-framework-secret:
 
-    .. code-block:: xml
+secret
+~~~~~~
 
-        <!-- config/packages/framework.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <container xmlns="http://symfony.com/schema/dic/services"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xmlns:framework="http://symfony.com/schema/dic/symfony"
-            xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
-                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+**type**: ``string`` **required**
 
-            <framework:config>
-                <!-- this manifest is applied to every asset (including packages) -->
-                <framework:assets json-manifest-path="%kernel.project_dir%/public/build/manifest.json">
-                <!-- you can use absolute URLs too and Symfony will download them automatically -->
-                <!-- <framework:assets json-manifest-path="https://cdn.example.com/manifest.json"> -->
-                    <!-- this package uses its own manifest (the default file is ignored) -->
-                    <!-- Throws an exception when an asset is not found in the manifest -->
-                    <framework:package
-                        name="foo_package"
-                        json-manifest-path="%kernel.project_dir%/public/build/a_different_manifest.json" strict-mode="%kernel.debug%"/>
-                    <!-- this package uses the global manifest (the default file is used) -->
-                    <framework:package
-                        name="bar_package"
-                        base-path="/images"/>
-                </framework:assets>
-            </framework:config>
-        </container>
+This is a string that should be unique to your application and it's commonly
+used to add more entropy to security related operations. Its value should
+be a series of characters, numbers and symbols chosen randomly and the
+recommended length is around 32 characters.
 
-    .. code-block:: php
+In practice, Symfony uses this value for encrypting the cookies used
+in the :doc:`remember me functionality </security/remember_me>` and for
+creating signed URIs when using :ref:`ESI (Edge Side Includes) <edge-side-includes>`.
+That's why you should treat this value as if it were a sensitive credential and
+**never make it public**.
 
-        // config/packages/framework.php
-        use Symfony\Config\FrameworkConfig;
+This option becomes the service container parameter named ``kernel.secret``,
+which you can use whenever the application needs an immutable random string
+to add more entropy.
 
-        return static function (FrameworkConfig $framework): void {
-            // ...
-            $framework->assets()
-                // this manifest is applied to every asset (including packages)
-                ->jsonManifestPath('%kernel.project_dir%/public/build/manifest.json');
+As with any other security-related parameter, it is a good practice to change
+this value from time to time. However, keep in mind that changing this value
+will invalidate all signed URIs and Remember Me cookies. That's why, after
+changing this value, you should regenerate the application cache and log
+out all the application users.
 
-            // you can use absolute URLs too and Symfony will download them automatically
-            // 'json_manifest_path' => 'https://cdn.example.com/manifest.json',
-            $framework->assets()->package('foo_package')
-                // this package uses its own manifest (the default file is ignored)
-                ->jsonManifestPath('%kernel.project_dir%/public/build/a_different_manifest.json')
-                // Throws an exception when an asset is not found in the manifest
-                ->setStrictMode('%kernel.debug%');
+secrets
+~~~~~~~
 
-            $framework->assets()->package('bar_package')
-                // this package uses the global manifest (the default file is used)
-                ->basePath('/images');
-        };
+decryption_env_var
+..................
 
-.. note::
+**type**: ``string`` **default**: ``base64:default::SYMFONY_DECRYPTION_SECRET``
 
-    This parameter cannot be set at the same time as ``version`` or ``version_strategy``.
-    Additionally, this option cannot be nullified at the package scope if a global manifest
-    file is specified.
+The env var name that contains the vault decryption secret. By default, this
+value will be decoded from base64.
 
-.. tip::
+enabled
+.......
 
-    If you request an asset that is *not found* in the ``manifest.json`` file, the original -
-    *unmodified* - asset path will be returned.
-    You can set ``strict_mode`` to ``true`` to get an exception when an asset is *not found*.
+**type**: ``boolean`` **default**: ``true``
 
-.. note::
+Whether to enable or not secrets managements.
 
-    If a URL is set, the JSON manifest is downloaded on each request using the `http_client`_.
+local_dotenv_file
+.................
 
-.. _reference-assets-strict-mode:
+**type**: ``string`` **default**: ``%kernel.project_dir%/.env.%kernel.environment%.local``
 
-strict_mode
-...........
+The path to the local ``.env`` file. This file must contain the vault
+decryption key, given by the ``decryption_env_var`` option.
 
-**type**: ``boolean`` **default**: ``false``
+vault_directory
+...............
 
-When enabled, the strict mode asserts that all requested assets are in the
-manifest file. This option is useful to detect typos or missing assets, the
-recommended value is ``%kernel.debug%``.
+**type**: ``string`` **default**: ``%kernel.project_dir%/config/secrets/%kernel.runtime_environment%``
 
-translator
-~~~~~~~~~~
+The directory to store the secret vault. By default, the path includes the value
+of the :ref:`kernel.runtime_environment <configuration-kernel-runtime-environment>`
+parameter.
 
-cache_dir
-.........
+semaphore
+~~~~~~~~~
 
-**type**: ``string`` | ``null`` **default**: ``%kernel.cache_dir%/translations``
+**type**: ``string`` | ``array``
 
-Defines the directory where the translation cache is stored. Use ``null`` to
-disable this cache.
+The default semaphore adapter. Store's DSN are also allowed.
 
-.. _reference-translator-enabled:
+.. _reference-semaphore-enabled:
 
 enabled
 .......
 
-**type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation
+**type**: ``boolean`` **default**: ``true``
 
-Whether or not to enable the ``translator`` service in the service container.
+Whether to enable the support for semaphore or not. This setting is
+automatically set to ``true`` when one of the child settings is configured.
 
-.. _fallback:
+.. _reference-semaphore-resources:
 
-fallbacks
+resources
 .........
 
-**type**: ``string|array`` **default**: value of `default_locale`_
+**type**: ``array``
 
-This option is used when the translation key for the current locale wasn't
-found.
+A map of semaphore stores to be created by the framework extension, with
+the name as key and DSN as value:
 
-.. seealso::
+.. configuration-block::
 
-    For more details, see :doc:`/translation`.
+    .. code-block:: yaml
 
-.. _reference-framework-translator-logging:
+        # config/packages/semaphore.yaml
+        framework:
+            semaphore: '%env(SEMAPHORE_DSN)%'
 
-logging
-.......
+    .. code-block:: xml
 
-**default**: ``true`` when the debug mode is enabled, ``false`` otherwise.
+        <!-- config/packages/semaphore.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
-When ``true``, a log entry is made whenever the translator cannot find a translation
-for a given key. The logs are made to the ``translation`` channel at the
-``debug`` level for keys where there is a translation in the fallback
-locale, and the ``warning`` level if there is no translation to use at all.
+            <framework:config>
+                <framework:semaphore>
+                    <framework:resource name="default">%env(SEMAPHORE_DSN)%</framework:resource>
+                </framework:semaphore>
+            </framework:config>
+        </container>
 
-.. _reference-framework-translator-formatter:
+    .. code-block:: php
 
-formatter
-.........
+        // config/packages/semaphore.php
+        use Symfony\Config\FrameworkConfig;
 
-**type**: ``string`` **default**: ``translator.formatter.default``
+        return static function (FrameworkConfig $framework): void {
+            $framework->semaphore()
+                ->resource('default', ['%env(SEMAPHORE_DSN)%']);
+        };
 
-The ID of the service used to format translation messages. The service class
-must implement the :class:`Symfony\\Component\\Translation\\Formatter\\MessageFormatterInterface`.
+.. _reference-semaphore-resources-name:
 
-.. _reference-translator-paths:
+name
+""""
+
+**type**: ``prototype``
+
+Name of the semaphore you want to create.
+
+.. _configuration-framework-serializer:
+
+serializer
+~~~~~~~~~~
+
+.. _reference-serializer-circular_reference_handler:
 
-paths
-.....
+circular_reference_handler
+..........................
 
-**type**: ``array`` **default**: ``[]``
+**type** ``string``
 
-This option allows to define an array of paths where the component will look
-for translation files. The later a path is added, the more priority it has
-(translations from later paths overwrite earlier ones). Translations from the
-:ref:`default_path <reference-translator-default_path>` have more priority than
-translations from all these paths.
+The service id that is used as the circular reference handler of the default
+serializer. The service has to implement the magic ``__invoke($object)``
+method.
 
-.. _reference-translator-default_path:
+.. seealso::
 
-default_path
-............
+    For more information, see
+    :ref:`component-serializer-handling-circular-references`.
 
-**type**: ``string`` **default**: ``%kernel.project_dir%/translations``
+default_context
+...............
 
-This option allows to define the path where the application translations files
-are stored.
+**type**: ``array`` **default**: ``[]``
 
-.. _reference-translator-providers:
+A map with default context options that will be used with each ``serialize`` and ``deserialize``
+call. This can be used for example to set the json encoding behavior by setting ``json_encode_options``
+to a `json_encode flags bitmask`_.
 
-providers
-.........
+You can inspect the :ref:`serializer context builders <serializer-using-context-builders>`
+to discover the available settings.
 
-**type**: ``array`` **default**: ``[]``
+.. _reference-serializer-enable_annotations:
 
-This option enables and configures :ref:`translation providers <translation-providers>`
-to push and pull your translations to/from third party translation services.
+enable_attributes
+.................
 
-property_access
-~~~~~~~~~~~~~~~
+**type**: ``boolean`` **default**: ``true``
 
-magic_call
-..........
+Enables support for `PHP attributes`_ in the serializer component.
 
-**type**: ``boolean`` **default**: ``false``
+.. seealso::
 
-When enabled, the ``property_accessor`` service uses PHP's
-:ref:`magic __call() method <components-property-access-magic-call>` when
-its ``getValue()`` method is called.
+    See :ref:`the reference <reference-attributes-serializer>` for a list of supported annotations.
 
-magic_get
-.........
+.. _reference-serializer-enabled:
 
-**type**: ``boolean`` **default**: ``true``
+enabled
+.......
 
-When enabled, the ``property_accessor`` service uses PHP's
-:ref:`magic __get() method <components-property-access-magic-get>` when
-its ``getValue()`` method is called.
+**type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation
 
-magic_set
-.........
+Whether to enable the ``serializer`` service or not in the service container.
 
-**type**: ``boolean`` **default**: ``true``
+.. _reference-serializer-mapping:
 
-When enabled, the ``property_accessor`` service uses PHP's
-:ref:`magic __set() method <components-property-access-writing-to-objects>` when
-its ``setValue()`` method is called.
+mapping
+.......
 
-throw_exception_on_invalid_index
-................................
+.. _reference-serializer-mapping-paths:
 
-**type**: ``boolean`` **default**: ``false``
+paths
+"""""
 
-When enabled, the ``property_accessor`` service throws an exception when you
-try to access an invalid index of an array.
+**type**: ``array`` **default**: ``[]``
 
-throw_exception_on_invalid_property_path
-........................................
+This option allows to define an array of paths with files or directories where
+the component will look for additional serialization files.
 
-**type**: ``boolean`` **default**: ``true``
+.. _reference-serializer-name_converter:
 
-When enabled, the ``property_accessor`` service throws an exception when you
-try to access an invalid property path of an object.
+name_converter
+..............
 
-property_info
-~~~~~~~~~~~~~
+**type**: ``string``
 
-.. _reference-property-info-enabled:
+The name converter to use.
+The :class:`Symfony\\Component\\Serializer\\NameConverter\\CamelCaseToSnakeCaseNameConverter`
+name converter can enabled by using the ``serializer.name_converter.camel_case_to_snake_case``
+value.
 
-enabled
-.......
+.. seealso::
 
-**type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation
+    For more information, see :ref:`serializer-name-conversion`.
 
-.. _reference-validation:
+.. _config-framework-session:
 
-validation
-~~~~~~~~~~
+session
+~~~~~~~
 
-.. _reference-validation-auto-mapping:
+cache_limiter
+.............
 
-auto_mapping
-............
+**type**: ``string`` **default**: ``0``
 
-**type**: ``array`` **default**: ``[]``
+If set to ``0``, Symfony won't set any particular header related to the cache
+and it will rely on ``php.ini``'s `session.cache_limiter`_ directive.
 
-Defines the Doctrine entities that will be introspected to add
-:ref:`automatic validation constraints <automatic_object_validation>` to them:
+Unlike the other session options, ``cache_limiter`` is set as a regular
+:ref:`container parameter <configuration-parameters>`:
 
 .. configuration-block::
 
     .. code-block:: yaml
 
-        framework:
-            validation:
-                auto_mapping:
-                    # an empty array means that all entities that belong to that
-                    # namespace will add automatic validation
-                    'App\Entity\': []
-                    'Foo\': ['Foo\Some\Entity', 'Foo\Another\Entity']
+        # config/services.yaml
+        parameters:
+            session.storage.options:
+                cache_limiter: 0
 
     .. code-block:: xml
 
-        <!-- config/packages/framework.xml -->
+        <!-- config/services.xml -->
         <?xml version="1.0" encoding="UTF-8" ?>
         <container xmlns="http://symfony.com/schema/dic/services"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xmlns:framework="http://symfony.com/schema/dic/symfony"
             xsi:schemaLocation="http://symfony.com/schema/dic/services
-                https://symfony.com/schema/dic/services/services-1.0.xsd
-                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
-
-            <framework:config>
-                <framework:validation>
-                    <framework:auto-mapping>
-                        <framework:service namespace="App\Entity\"/>
+                https://symfony.com/schema/dic/services/services-1.0.xsd">
 
-                        <framework:service namespace="Foo\">Foo\Some\Entity</framework:service>
-                        <framework:service namespace="Foo\">Foo\Another\Entity</framework:service>
-                    </framework:auto-mapping>
-                </framework:validation>
-            </framework:config>
+            <parameters>
+                <parameter key="session.storage.options" type="collection">
+                    <parameter key="cache_limiter">0</parameter>
+                </parameter>
+            </parameters>
         </container>
 
     .. code-block:: php
 
-        // config/packages/framework.php
-        use Symfony\Config\FrameworkConfig;
-
-        return static function (FrameworkConfig $framework): void {
-            $framework->validation()
-                ->autoMapping()
-                    ->paths([
-                        'App\\Entity\\' => [],
-                        'Foo\\' => ['Foo\\Some\\Entity', 'Foo\\Another\\Entity'],
-                    ]);
-        };
-
-.. _reference-validation-enabled:
+        // config/services.php
+        $container->setParameter('session.storage.options', [
+            'cache_limiter' => 0,
+        ]);
 
-enabled
-.......
+Be aware that if you configure it, you'll have to set other session-related options
+as parameters as well.
 
-**type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation
+cookie_domain
+.............
 
-Whether or not to enable validation support.
+**type**: ``string``
 
-This option will automatically be set to ``true`` when one of the child
-settings is configured.
+This determines the domain to set in the session cookie.
 
-.. _reference-validation-enable_annotations:
+If not set, ``php.ini``'s `session.cookie_domain`_ directive will be relied on.
 
-enable_attributes
-.................
+cookie_httponly
+...............
 
 **type**: ``boolean`` **default**: ``true``
 
-If this option is enabled, validation constraints can be defined using `PHP attributes`_.
+This determines whether cookies should only be accessible through the HTTP
+protocol. This means that the cookie won't be accessible by scripting
+languages, such as JavaScript. This setting can effectively help to reduce
+identity theft through :ref:`XSS attacks <xss-attacks>`.
 
-translation_domain
-..................
+cookie_lifetime
+...............
 
-**type**: ``string | false`` **default**: ``validators``
+**type**: ``integer``
 
-The translation domain that is used when translating validation constraint
-error messages. Use false to disable translations.
+This determines the lifetime of the session - in seconds.
+Setting this value to ``0`` means the cookie is valid for
+the length of the browser session.
 
-.. _reference-validation-not-compromised-password:
+If not set, ``php.ini``'s `session.cookie_lifetime`_ directive will be relied on.
 
-not_compromised_password
-........................
+cookie_path
+...........
 
-The :doc:`NotCompromisedPassword </reference/constraints/NotCompromisedPassword>`
-constraint makes HTTP requests to a public API to check if the given password
-has been compromised in a data breach.
+**type**: ``string``
 
-.. _reference-validation-not-compromised-password-enabled:
+This determines the path to set in the session cookie.
 
-enabled
-"""""""
+If not set, ``php.ini``'s `session.cookie_path`_ directive will be relied on.
 
-**type**: ``boolean`` **default**: ``true``
+cookie_samesite
+...............
 
-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
-continuous integration servers.
+**type**: ``string`` or ``null`` **default**: ``null``
 
-endpoint
-""""""""
+It controls the way cookies are sent when the HTTP request did not originate
+from the same domain that is associated with the cookies. Setting this option is
+recommended to mitigate `CSRF security attacks`_.
 
-**type**: ``string`` **default**: ``null``
+By default, browsers send all cookies related to the domain of the HTTP request.
+This may be a problem for example when you visit a forum and some malicious
+comment includes a link like ``https://some-bank.com/?send_money_to=attacker&amount=1000``.
+If you were previously logged into your bank website, the browser will send all
+those cookies when making that HTTP request.
 
-By default, the :doc:`NotCompromisedPassword </reference/constraints/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
-checks. It's useful for example when the Symfony application is run in an
-intranet without public access to the internet.
+The possible values for this option are:
+
+* ``null``, use ``php.ini``'s `session.cookie_samesite`_ directive.
+* ``'none'`` (or the ``Symfony\Component\HttpFoundation\Cookie::SAMESITE_NONE`` constant), use it to allow
+  sending of cookies when the HTTP request originated from a different domain
+  (previously this was the default behavior of null, but in newer browsers ``'lax'``
+  would be applied when the header has not been set)
+* ``'strict'`` (or the ``Cookie::SAMESITE_STRICT`` constant), use it to never
+  send any cookie when the HTTP request did not originate from the same domain.
+* ``'lax'`` (or the ``Cookie::SAMESITE_LAX`` constant), use it to allow sending
+  cookies when the request originated from a different domain, but only when the
+  user consciously made the request (by clicking a link or submitting a form
+  with the ``GET`` method).
 
-static_method
+cookie_secure
 .............
 
-**type**: ``string | array`` **default**: ``['loadValidatorMetadata']``
-
-Defines the name of the static method which is called to load the validation
-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.
-
-.. _reference-validation-email_validation_mode:
-
-email_validation_mode
-.....................
+**type**: ``boolean`` or ``'auto'``
 
-**type**: ``string`` **default**: ``html5``
+This determines whether cookies should only be sent over secure connections. In
+addition to ``true`` and ``false``, there's a special ``'auto'`` value that
+means ``true`` for HTTPS requests and ``false`` for HTTP requests.
 
-Sets the default value for the
-:ref:`"mode" option of the Email validator <reference-constraint-email-mode>`.
+If not set, ``php.ini``'s `session.cookie_secure`_ directive will be relied on.
 
-.. _reference-validation-mapping:
+.. _reference-session-enabled:
 
-mapping
+enabled
 .......
 
-.. _reference-validation-mapping-paths:
-
-paths
-"""""
-
-**type**: ``array`` **default**: ``['config/validation/']``
+**type**: ``boolean`` **default**: ``true``
 
-This option allows to define an array of paths with files or directories where
-the component will look for additional validation files:
+Whether to enable the session support in the framework.
 
 .. configuration-block::
 
@@ -2833,10 +3003,8 @@ the component will look for additional validation files:
 
         # config/packages/framework.yaml
         framework:
-            validation:
-                mapping:
-                    paths:
-                        - "%kernel.project_dir%/config/validation/"
+            session:
+                enabled: true
 
     .. code-block:: xml
 
@@ -2850,11 +3018,7 @@ the component will look for additional validation files:
                 http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
             <framework:config>
-                <framework:validation>
-                    <framework:mapping>
-                        <framework:path>%kernel.project_dir%/config/validation/</framework:path>
-                    </framework:mapping>
-                </framework:validation>
+                <framework:session enabled="true"/>
             </framework:config>
         </container>
 
@@ -2864,152 +3028,163 @@ the component will look for additional validation files:
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
-            $framework->validation()
-                ->mapping()
-                    ->paths(['%kernel.project_dir%/config/validation/']);
+            $framework->session()
+                ->enabled(true);
         };
 
-annotations
-~~~~~~~~~~~
-
-.. _reference-annotations-cache:
-
-cache
-.....
+gc_divisor
+..........
 
-**type**: ``string`` **default**: ``php_array``
+**type**: ``integer``
 
-This option can be one of the following values:
+See `gc_probability`_.
 
-php_array
-    Use a PHP array to cache annotations in memory
-file
-    Use the filesystem to cache annotations
-none
-    Disable the caching of annotations
+If not set, ``php.ini``'s `session.gc_divisor`_ directive will be relied on.
 
-file_cache_dir
+gc_maxlifetime
 ..............
 
-**type**: ``string`` **default**: ``%kernel.cache_dir%/annotations``
-
-The directory to store cache files for annotations, in case
-``annotations.cache`` is set to ``'file'``.
-
-debug
-.....
-
-**type**: ``boolean`` **default**: ``%kernel.debug%``
-
-Whether to enable debug mode for caching. If enabled, the cache will
-automatically update when the original file is changed (both with code and
-annotation changes). For performance reasons, it is recommended to disable
-debug mode in production, which will happen automatically if you use the
-default value.
-
-.. _configuration-framework-serializer:
-
-serializer
-~~~~~~~~~~
-
-.. _reference-serializer-enabled:
+**type**: ``integer``
 
-enabled
-.......
+This determines the number of seconds after which data will be seen as "garbage"
+and potentially cleaned up. Garbage collection may occur during session
+start and depends on `gc_divisor`_ and `gc_probability`_.
 
-**type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation
+If not set, ``php.ini``'s `session.gc_maxlifetime`_ directive will be relied on.
 
-Whether to enable the ``serializer`` service or not in the service container.
+gc_probability
+..............
 
-.. _reference-serializer-enable_annotations:
+**type**: ``integer``
 
-enable_attributes
-.................
+This defines the probability that the garbage collector (GC) process is
+started on every session initialization. The probability is calculated by
+using ``gc_probability`` / ``gc_divisor``, e.g. 1/100 means there is a 1%
+chance that the GC process will start on each request.
 
-**type**: ``boolean`` **default**: ``true``
+If not set, Symfony will use the value of the `session.gc_probability`_ directive
+in the ``php.ini`` configuration file.
 
-Enables support for `PHP attributes`_ in the serializer component.
+.. versionadded:: 7.2
 
-.. seealso::
+    Relying on ``php.ini``'s directive as default for ``gc_probability`` was
+    introduced in Symfony 7.2.
 
-    See :ref:`the reference <reference-attributes-serializer>` for a list of supported annotations.
+.. _config-framework-session-handler-id:
 
-.. _reference-serializer-name_converter:
+handler_id
+..........
 
-name_converter
-..............
+**type**: ``string`` | ``null`` **default**: ``null``
 
-**type**: ``string``
+If ``framework.session.save_path`` is not set, the default value of this option
+is ``null``, which means to use the session handler configured in php.ini. If the
+``framework.session.save_path`` option is set, then Symfony stores sessions using
+the native file session handler.
 
-The name converter to use.
-The :class:`Symfony\\Component\\Serializer\\NameConverter\\CamelCaseToSnakeCaseNameConverter`
-name converter can enabled by using the ``serializer.name_converter.camel_case_to_snake_case``
-value.
+It is possible to :ref:`store sessions in a database <session-database>`,
+and also to configure the session handler with a DSN:
 
-.. seealso::
+.. configuration-block::
 
-    For more information, see :ref:`serializer-name-conversion`.
+    .. code-block:: yaml
 
-.. _reference-serializer-circular_reference_handler:
+        # config/packages/framework.yaml
+        framework:
+            session:
+                # a few possible examples
+                handler_id: 'redis://localhost'
+                handler_id: '%env(REDIS_URL)%'
+                handler_id: '%env(DATABASE_URL)%'
+                handler_id: 'file://%kernel.project_dir%/var/sessions'
 
-circular_reference_handler
-..........................
+    .. code-block:: xml
 
-**type** ``string``
+        <!-- config/packages/framework.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+            <framework:config>
+                <!-- a few possible examples -->
+                <framework:session enabled="true"
+                    handler-id="redis://localhost"
+                    handler-id="%env(REDIS_URL)%"
+                    handler-id="%env(DATABASE_URL)%"
+                    handler-id="file://%kernel.project_dir%/var/sessions"/>
+            </framework:config>
+        </container>
 
-The service id that is used as the circular reference handler of the default
-serializer. The service has to implement the magic ``__invoke($object)``
-method.
+    .. code-block:: php
 
-.. seealso::
+        // config/packages/framework.php
+        use function Symfony\Component\DependencyInjection\Loader\Configurator\env;
+        use Symfony\Config\FrameworkConfig;
 
-    For more information, see
-    :ref:`component-serializer-handling-circular-references`.
+        return static function (FrameworkConfig $framework): void {
+            // ...
 
-.. _reference-serializer-mapping:
+            $framework->session()
+                // a few possible examples
+                ->handlerId('redis://localhost')
+                ->handlerId(env('REDIS_URL'))
+                ->handlerId(env('DATABASE_URL'))
+                ->handlerId('file://%kernel.project_dir%/var/sessions');
+        };
 
-mapping
-.......
+.. note::
 
-.. _reference-serializer-mapping-paths:
+    Supported DSN protocols are the following:
 
-paths
-"""""
+    * ``file``
+    * ``redis``
+    * ``rediss`` (Redis over TLS)
+    * ``memcached`` (requires :doc:`symfony/cache </components/cache>`)
+    * ``pdo_oci`` (requires :doc:`doctrine/dbal </doctrine/dbal>`)
+    * ``mssql``
+    * ``mysql``
+    * ``mysql2``
+    * ``pgsql``
+    * ``postgres``
+    * ``postgresql``
+    * ``sqlsrv``
+    * ``sqlite``
+    * ``sqlite3``
 
-**type**: ``array`` **default**: ``[]``
+.. _reference-session-metadata-update-threshold:
 
-This option allows to define an array of paths with files or directories where
-the component will look for additional serialization files.
+metadata_update_threshold
+.........................
 
-default_context
-...............
+**type**: ``integer`` **default**: ``0``
 
-**type**: ``array`` **default**: ``[]``
+This is how many seconds to wait between updating/writing the session metadata.
+This can be useful if, for some reason, you want to limit the frequency at which
+the session persists, instead of doing that on every request.
 
-A map with default context options that will be used with each ``serialize`` and ``deserialize``
-call. This can be used for example to set the json encoding behavior by setting ``json_encode_options``
-to a `json_encode flags bitmask`_.
+.. _name:
 
-You can inspect the :ref:`serializer context builders <serializer-using-context-builders>`
-to discover the available settings.
+name
+....
 
-php_errors
-~~~~~~~~~~
+**type**: ``string``
 
-log
-...
+This specifies the name of the session cookie.
 
-**type**: ``boolean`` | ``int`` | ``array<int, string>`` **default**: ``true``
+If not set, ``php.ini``'s `session.name`_ directive will be relied on.
 
-Use the application logger instead of the PHP logger for logging PHP errors.
-When an integer value is used, it defines a bitmask of PHP errors that will
-be logged. Those integer values must be the same used in the
-`error_reporting PHP option`_. The default log levels will be used for each
-PHP error.
-When a boolean value is used, ``true`` enables logging for all PHP errors
-while ``false`` disables logging entirely.
+save_path
+.........
 
-This option also accepts a map of PHP errors to log levels:
+**type**: ``string`` | ``null`` **default**: ``%kernel.cache_dir%/sessions``
+
+This determines the argument to be passed to the save handler. If you choose
+the default file handler, this is the path where the session files are created.
+
+If ``null``, ``php.ini``'s `session.save_path`_ directive will be relied on:
 
 .. configuration-block::
 
@@ -3017,23 +3192,8 @@ This option also accepts a map of PHP errors to log levels:
 
         # config/packages/framework.yaml
         framework:
-            php_errors:
-                log:
-                    !php/const \E_DEPRECATED: !php/const Psr\Log\LogLevel::ERROR
-                    !php/const \E_USER_DEPRECATED: !php/const Psr\Log\LogLevel::ERROR
-                    !php/const \E_NOTICE: !php/const Psr\Log\LogLevel::ERROR
-                    !php/const \E_USER_NOTICE: !php/const Psr\Log\LogLevel::ERROR
-                    !php/const \E_STRICT: !php/const Psr\Log\LogLevel::ERROR
-                    !php/const \E_WARNING: !php/const Psr\Log\LogLevel::ERROR
-                    !php/const \E_USER_WARNING: !php/const Psr\Log\LogLevel::ERROR
-                    !php/const \E_COMPILE_WARNING: !php/const Psr\Log\LogLevel::ERROR
-                    !php/const \E_CORE_WARNING: !php/const Psr\Log\LogLevel::ERROR
-                    !php/const \E_USER_ERROR: !php/const Psr\Log\LogLevel::CRITICAL
-                    !php/const \E_RECOVERABLE_ERROR: !php/const Psr\Log\LogLevel::CRITICAL
-                    !php/const \E_COMPILE_ERROR: !php/const Psr\Log\LogLevel::CRITICAL
-                    !php/const \E_PARSE: !php/const Psr\Log\LogLevel::CRITICAL
-                    !php/const \E_ERROR: !php/const Psr\Log\LogLevel::CRITICAL
-                    !php/const \E_CORE_ERROR: !php/const Psr\Log\LogLevel::CRITICAL
+            session:
+                save_path: ~
 
     .. code-block:: xml
 
@@ -3047,322 +3207,267 @@ This option also accepts a map of PHP errors to log levels:
                 http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
             <framework:config>
-                <!-- in XML configuration you cannot use PHP constants as the value of
-                     the 'type' attribute, which makes this format way less readable.
-                     Consider using YAML or PHP for this configuration -->
-                <framework:log type="8" logLevel="error"/>
-                <framework:log type="2" logLevel="error"/>
-                <!-- ... -->
+                <framework:session save-path="null"/>
             </framework:config>
         </container>
 
     .. code-block:: php
 
         // config/packages/framework.php
-        use Psr\Log\LogLevel;
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
-            $framework->phpErrors()->log(\E_DEPRECATED, LogLevel::ERROR);
-            $framework->phpErrors()->log(\E_USER_DEPRECATED, LogLevel::ERROR);
-            // ...
+            $framework->session()
+                ->savePath(null);
         };
 
-throw
-.....
-
-**type**: ``boolean`` **default**: ``%kernel.debug%``
-
-Throw PHP errors as ``\ErrorException`` instances. The parameter
-``debug.error_handler.throw_at`` controls the threshold.
-
-.. _reference-cache:
-
-cache
-~~~~~
-
-.. _reference-cache-app:
-
-app
-...
-
-**type**: ``string`` **default**: ``cache.adapter.filesystem``
+sid_bits_per_character
+......................
 
-The cache adapter used by the ``cache.app`` service. The FrameworkBundle
-ships with multiple adapters: ``cache.adapter.apcu``, ``cache.adapter.system``,
-``cache.adapter.filesystem``, ``cache.adapter.psr6``, ``cache.adapter.redis``,
-``cache.adapter.memcached``, ``cache.adapter.pdo`` and
-``cache.adapter.doctrine_dbal``.
+**type**: ``integer``
 
-There's also a special adapter called ``cache.adapter.array`` which stores
-contents in memory using a PHP array and it's used to disable caching (mostly on
-the ``dev`` environment).
+This determines the number of bits in the encoded session ID character. The possible
+values are ``4`` (0-9, a-f), ``5`` (0-9, a-v), and ``6`` (0-9, a-z, A-Z, "-", ",").
+The more bits results in stronger session ID. ``5`` is recommended value for
+most environments.
 
-.. tip::
+If not set, ``php.ini``'s `session.sid_bits_per_character`_ directive will be relied on.
 
-    It might be tough to understand at the beginning, so to avoid confusion
-    remember that all pools perform the same actions but on different medium
-    given the adapter they are based on. Internally, a pool wraps the definition
-    of an adapter.
+.. deprecated:: 7.2
 
-.. _reference-cache-system:
+    The ``sid_bits_per_character`` option was deprecated in Symfony 7.2. No alternative
+    is provided as PHP 8.4 has deprecated the related option.
 
-system
-......
+sid_length
+..........
 
-**type**: ``string`` **default**: ``cache.adapter.system``
+**type**: ``integer``
 
-The cache adapter used by the ``cache.system`` service. It supports the same
-adapters available for the ``cache.app`` service.
+This determines the length of session ID string, which can be an integer between
+``22`` and ``256`` (both inclusive), ``32`` being the recommended value. Longer
+session IDs are harder to guess.
 
-directory
-.........
+If not set, ``php.ini``'s `session.sid_length`_ directive will be relied on.
 
-**type**: ``string`` **default**: ``%kernel.cache_dir%/pools``
+.. deprecated:: 7.2
 
-The path to the cache directory used by services inheriting from the
-``cache.adapter.filesystem`` adapter (including ``cache.app``).
+    The ``sid_length`` option was deprecated in Symfony 7.2. No alternative is
+    provided as PHP 8.4 has deprecated the related option.
 
-default_doctrine_provider
-.........................
+.. _storage_id:
 
-**type**: ``string``
+storage_factory_id
+..................
 
-The service name to use as your default Doctrine provider. The provider is
-available as the ``cache.default_doctrine_provider`` service.
+**type**: ``string`` **default**: ``session.storage.factory.native``
 
-default_psr6_provider
-.....................
+The service ID used for creating the ``SessionStorageInterface`` that stores
+the session. This service is available in the Symfony application via the
+``session.storage.factory`` service alias. The class has to implement
+:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageFactoryInterface`.
+To see a list of all available storages, run:
 
-**type**: ``string``
+.. code-block:: terminal
 
-The service name to use as your default PSR-6 provider. It is available as
-the ``cache.default_psr6_provider`` service.
+    $ php bin/console debug:container session.storage.factory.
 
-default_redis_provider
-......................
+use_cookies
+...........
 
-**type**: ``string`` **default**: ``redis://localhost``
+**type**: ``boolean``
 
-The DSN to use by the Redis provider. The provider is available as the ``cache.default_redis_provider``
-service.
+This specifies if the session ID is stored on the client side using cookies or
+not.
 
-default_memcached_provider
-..........................
+If not set, ``php.ini``'s `session.use_cookies`_ directive will be relied on.
 
-**type**: ``string`` **default**: ``memcached://localhost``
+ssi
+~~~
 
-The DSN to use by the Memcached provider. The provider is available as the ``cache.default_memcached_provider``
-service.
+enabled
+.......
 
-default_pdo_provider
-....................
+**type**: ``boolean`` **default**: ``false``
 
-**type**: ``string`` **default**: ``doctrine.dbal.default_connection``
+Whether to enable or not SSI support in your application.
 
-The service id of the database connection, which should be either a PDO or a
-Doctrine DBAL instance. The provider is available as the ``cache.default_pdo_provider``
-service.
+.. _reference-framework-test:
 
-pools
-.....
+test
+~~~~
 
-**type**: ``array``
+**type**: ``boolean``
 
-A list of cache pools to be created by the framework extension.
+If this configuration setting is present (and not ``false``), then the services
+related to testing your application (e.g. ``test.client``) are loaded. This
+setting should be present in your ``test`` environment (usually via
+``config/packages/test/framework.yaml``).
 
 .. seealso::
 
-    For more information about how pools work, see :ref:`cache pools <component-cache-cache-pools>`.
-
-To configure a Redis cache pool with a default lifetime of 1 hour, do the following:
-
-.. configuration-block::
-
-    .. code-block:: yaml
-
-        # config/packages/framework.yaml
-        framework:
-            cache:
-                pools:
-                    cache.mycache:
-                        adapter: cache.adapter.redis
-                        default_lifetime: 3600
-
-    .. code-block:: xml
-
-        <!-- config/packages/framework.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <container xmlns="http://symfony.com/schema/dic/services"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xmlns:framework="http://symfony.com/schema/dic/symfony"
-            xsi:schemaLocation="http://symfony.com/schema/dic/services
-                https://symfony.com/schema/dic/services/services-1.0.xsd
-                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+    For more information, see :doc:`/testing`.
 
-            <framework:config>
-                <framework:cache>
-                    <framework:pool
-                        name="cache.mycache"
-                        adapter="cache.adapter.redis"
-                        default-lifetime="3600"
-                    />
-                </framework:cache>
-                <!-- ... -->
-            </framework:config>
-        </container>
+translator
+~~~~~~~~~~
 
-    .. code-block:: php
+cache_dir
+.........
 
-        // config/packages/framework.php
-        use Symfony\Config\FrameworkConfig;
+**type**: ``string`` | ``null`` **default**: ``%kernel.cache_dir%/translations``
 
-        return static function (FrameworkConfig $framework): void {
-            $framework->cache()
-                ->pool('cache.mycache')
-                    ->adapters(['cache.adapter.redis'])
-                    ->defaultLifetime(3600);
-        };
+Defines the directory where the translation cache is stored. Use ``null`` to
+disable this cache.
 
-.. _reference-cache-pools-name:
+.. _reference-translator-default_path:
 
-name
-""""
+default_path
+............
 
-**type**: ``prototype``
+**type**: ``string`` **default**: ``%kernel.project_dir%/translations``
 
-Name of the pool you want to create.
+This option allows to define the path where the application translations files
+are stored.
 
-.. note::
+.. _reference-translator-enabled:
 
-    Your pool name must differ from ``cache.app`` or ``cache.system``.
+enabled
+.......
 
-adapter
-"""""""
+**type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation
 
-**type**: ``string`` **default**: ``cache.app``
+Whether or not to enable the ``translator`` service in the service container.
 
-The service name of the adapter to use. You can specify one of the default
-services that follow the pattern ``cache.adapter.[type]``. Alternatively you
-can specify another cache pool as base, which will make this pool inherit the
-settings from the base pool as defaults.
+.. _fallback:
 
-.. note::
+fallbacks
+.........
 
-    Your service needs to implement the ``Psr\Cache\CacheItemPoolInterface`` interface.
+**type**: ``string|array`` **default**: value of `default_locale`_
 
-public
-""""""
+This option is used when the translation key for the current locale wasn't
+found.
 
-**type**: ``boolean`` **default**: ``false``
+.. seealso::
 
-Whether your service should be public or not.
+    For more details, see :doc:`/translation`.
 
-tags
-""""
+.. _reference-framework-translator-formatter:
 
-**type**: ``boolean`` | ``string`` **default**: ``null``
+formatter
+.........
 
-Whether your service should be able to handle tags or not.
-Can also be the service id of another cache pool where tags will be stored.
+**type**: ``string`` **default**: ``translator.formatter.default``
 
-default_lifetime
-""""""""""""""""
+The ID of the service used to format translation messages. The service class
+must implement the :class:`Symfony\\Component\\Translation\\Formatter\\MessageFormatterInterface`.
 
-**type**: ``integer`` | ``string``
+.. _reference-framework-translator-logging:
 
-Default lifetime of your cache items. Give an integer value to set the default
-lifetime in seconds. A string value could be ISO 8601 time interval, like ``"PT5M"``
-or a PHP date expression that is accepted by ``strtotime()``, like ``"5 minutes"``.
+logging
+.......
 
-If no value is provided, the cache adapter will fallback to the default value on
-the actual cache storage.
+**default**: ``true`` when the debug mode is enabled, ``false`` otherwise.
 
-provider
-""""""""
+When ``true``, a log entry is made whenever the translator cannot find a translation
+for a given key. The logs are made to the ``translation`` channel at the
+``debug`` level for keys where there is a translation in the fallback
+locale, and the ``warning`` level if there is no translation to use at all.
 
-**type**: ``string``
+.. _reference-translator-paths:
 
-Overwrite the default service name or DSN respectively, if you do not want to
-use what is configured as ``default_X_provider`` under ``cache``. See the
-description of the default provider setting above for information on how to
-specify your specific provider.
+paths
+.....
 
-clearer
-"""""""
+**type**: ``array`` **default**: ``[]``
 
-**type**: ``string``
+This option allows to define an array of paths where the component will look
+for translation files. The later a path is added, the more priority it has
+(translations from later paths overwrite earlier ones). Translations from the
+:ref:`default_path <reference-translator-default_path>` have more priority than
+translations from all these paths.
 
-The cache clearer used to clear your PSR-6 cache.
+.. _reference-translator-providers:
 
-.. seealso::
+providers
+.........
 
-    For more information, see :class:`Symfony\\Component\\HttpKernel\\CacheClearer\\Psr6CacheClearer`.
+**type**: ``array`` **default**: ``[]``
 
-.. _reference-cache-prefix-seed:
+This option enables and configures :ref:`translation providers <translation-providers>`
+to push and pull your translations to/from third party translation services.
 
-prefix_seed
-...........
+trust_x_sendfile_type_header
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-**type**: ``string`` **default**: ``_%kernel.project_dir%.%kernel.container_class%``
+**type**: ``boolean`` **default**: ``%env(bool:default::SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER)%``
 
-This value is used as part of the "namespace" generated for the
-cache item keys. A common practice is to use the unique name of the application
-(e.g. ``symfony.com``) because that prevents naming collisions when deploying
-multiple applications into the same path (on different servers) that share the
-same cache backend.
+.. versionadded:: 7.2
 
-It's also useful when using `blue/green deployment`_ strategies and more
-generally, when you need to abstract out the actual deployment directory (for
-example, when warming caches offline).
+    In Symfony 7.2, the default value of this option was changed from ``false`` to the
+    value stored in the ``SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER`` environment variable.
 
-.. note::
+``X-Sendfile`` is a special HTTP header that tells web servers to replace the
+response contents by the file that is defined in that header. This improves
+performance because files are no longer served by your application but directly
+by the web server.
 
-    The ``prefix_seed`` option is used at compile time. This means
-    that any change made to this value after container's compilation
-    will have no effect.
+This configuration option determines whether to trust ``x-sendfile`` header for
+BinaryFileResponse. If enabled, Symfony calls the
+:method:`BinaryFileResponse::trustXSendfileTypeHeader <Symfony\\Component\\HttpFoundation\\BinaryFileResponse::trustXSendfileTypeHeader>`
+method automatically. It becomes the service container parameter named
+``kernel.trust_x_sendfile_type_header``.
 
-.. _reference-lock:
+.. _reference-framework-trusted-headers:
 
-lock
-~~~~
+trusted_headers
+~~~~~~~~~~~~~~~
 
-**type**: ``string`` | ``array``
+The ``trusted_headers`` option is needed to configure which client information
+should be trusted (e.g. their host) when running Symfony behind a load balancer
+or a reverse proxy. See :doc:`/deployment/proxies`.
 
-The default lock adapter. If not defined, the value is set to ``semaphore`` when
-available, or to ``flock`` otherwise. Store's DSN are also allowed.
+.. _configuration-framework-trusted-hosts:
 
-.. _reference-lock-enabled:
+trusted_hosts
+~~~~~~~~~~~~~
 
-enabled
-.......
+**type**: ``array`` | ``string`` **default**: ``['%env(default::SYMFONY_TRUSTED_HOSTS)%']``
 
-**type**: ``boolean`` **default**: ``true``
+.. versionadded:: 7.2
 
-Whether to enable the support for lock or not. This setting is
-automatically set to ``true`` when one of the child settings is configured.
+    In Symfony 7.2, the default value of this option was changed from ``[]`` to the
+    value stored in the ``SYMFONY_TRUSTED_HOSTS`` environment variable.
 
-.. _reference-lock-resources:
+A lot of different attacks have been discovered relying on inconsistencies
+in handling the ``Host`` header by various software (web servers, reverse
+proxies, web frameworks, etc.). Basically, every time the framework is
+generating an absolute URL (when sending an email to reset a password for
+instance), the host might have been manipulated by an attacker.
 
-resources
-.........
+.. seealso::
 
-**type**: ``array``
+    You can read `HTTP Host header attacks`_ for more information about
+    these kinds of attacks.
 
-A map of lock stores to be created by the framework extension, with
-the name as key and DSN as value:
+The Symfony :method:`Request::getHost() <Symfony\\Component\\HttpFoundation\\Request::getHost>`
+method might be vulnerable to some of these attacks because it depends on
+the configuration of your web server. One simple solution to avoid these
+attacks is to configure a list of hosts that your Symfony application can respond
+to. That's the purpose of this ``trusted_hosts`` option. If the incoming
+request's hostname doesn't match one of the regular expressions in this list,
+the application won't respond and the user will receive a 400 response.
 
 .. configuration-block::
 
     .. code-block:: yaml
 
-        # config/packages/lock.yaml
+        # config/packages/framework.yaml
         framework:
-            lock: '%env(LOCK_DSN)%'
+            trusted_hosts:  ['^example\.com$', '^example\.org$']
 
     .. code-block:: xml
 
-        <!-- config/packages/lock.xml -->
+        <!-- config/packages/framework.xml -->
         <?xml version="1.0" encoding="UTF-8" ?>
         <container xmlns="http://symfony.com/schema/dic/services"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -3372,73 +3477,76 @@ the name as key and DSN as value:
                 http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
             <framework:config>
-                <framework:lock>
-                    <framework:resource name="default">%env(LOCK_DSN)%</framework:resource>
-                </framework:lock>
+                <framework:trusted-host>^example\.com$</framework:trusted-host>
+                <framework:trusted-host>^example\.org$</framework:trusted-host>
+                <!-- ... -->
             </framework:config>
         </container>
 
     .. code-block:: php
 
-        // config/packages/lock.php
+        // config/packages/framework.php
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
-            $framework->lock()
-                ->resource('default', [env('LOCK_DSN')]);
+            $framework->trustedHosts(['^example\.com$', '^example\.org$']);
         };
 
-.. seealso::
-
-    For more details, see :doc:`/lock`.
-
-.. _reference-lock-resources-name:
+Hosts can also be configured to respond to any subdomain, via
+``^(.+\.)?example\.com$`` for instance.
 
-name
-""""
+In addition, you can also set the trusted hosts in the front controller
+using the ``Request::setTrustedHosts()`` method::
 
-**type**: ``prototype``
+    // public/index.php
+    Request::setTrustedHosts(['^(.+\.)?example\.com$', '^(.+\.)?example\.org$']);
 
-Name of the lock you want to create.
+The default value for this option is an empty array, meaning that the application
+can respond to any given host.
 
-semaphore
-~~~~~~~~~
+.. seealso::
 
-**type**: ``string`` | ``array``
+    Read more about this in the `Security Advisory Blog post`_.
 
-The default semaphore adapter. Store's DSN are also allowed.
+.. _reference-framework-trusted-proxies:
 
-.. _reference-semaphore-enabled:
+trusted_proxies
+~~~~~~~~~~~~~~~
 
-enabled
-.......
+The ``trusted_proxies`` option is needed to get precise information about the
+client (e.g. their IP address) when running Symfony behind a load balancer or a
+reverse proxy. See :doc:`/deployment/proxies`.
 
-**type**: ``boolean`` **default**: ``true``
+.. _reference-validation:
 
-Whether to enable the support for semaphore or not. This setting is
-automatically set to ``true`` when one of the child settings is configured.
+validation
+~~~~~~~~~~
 
-.. _reference-semaphore-resources:
+.. _reference-validation-auto-mapping:
 
-resources
-.........
+auto_mapping
+............
 
-**type**: ``array``
+**type**: ``array`` **default**: ``[]``
 
-A map of semaphore stores to be created by the framework extension, with
-the name as key and DSN as value:
+Defines the Doctrine entities that will be introspected to add
+:ref:`automatic validation constraints <automatic_object_validation>` to them:
 
 .. configuration-block::
 
     .. code-block:: yaml
 
-        # config/packages/semaphore.yaml
         framework:
-            semaphore: '%env(SEMAPHORE_DSN)%'
+            validation:
+                auto_mapping:
+                    # an empty array means that all entities that belong to that
+                    # namespace will add automatic validation
+                    'App\Entity\': []
+                    'Foo\': ['Foo\Some\Entity', 'Foo\Another\Entity']
 
     .. code-block:: xml
 
-        <!-- config/packages/semaphore.xml -->
+        <!-- config/packages/framework.xml -->
         <?xml version="1.0" encoding="UTF-8" ?>
         <container xmlns="http://symfony.com/schema/dic/services"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -3448,93 +3556,91 @@ the name as key and DSN as value:
                 http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
 
             <framework:config>
-                <framework:semaphore>
-                    <framework:resource name="default">%env(SEMAPHORE_DSN)%</framework:resource>
-                </framework:semaphore>
+                <framework:validation>
+                    <framework:auto-mapping>
+                        <framework:service namespace="App\Entity\"/>
+
+                        <framework:service namespace="Foo\">Foo\Some\Entity</framework:service>
+                        <framework:service namespace="Foo\">Foo\Another\Entity</framework:service>
+                    </framework:auto-mapping>
+                </framework:validation>
             </framework:config>
         </container>
 
     .. code-block:: php
 
-        // config/packages/semaphore.php
+        // config/packages/framework.php
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
-            $framework->semaphore()
-                ->resource('default', ['%env(SEMAPHORE_DSN)%']);
+            $framework->validation()
+                ->autoMapping()
+                    ->paths([
+                        'App\\Entity\\' => [],
+                        'Foo\\' => ['Foo\\Some\\Entity', 'Foo\\Another\\Entity'],
+                    ]);
         };
 
-.. _reference-semaphore-resources-name:
-
-name
-""""
-
-**type**: ``prototype``
-
-Name of the semaphore you want to create.
+.. _reference-validation-email_validation_mode:
 
-mailer
-~~~~~~
+email_validation_mode
+.....................
 
-.. _mailer-dsn:
+**type**: ``string`` **default**: ``html5``
 
-dsn
-...
+Sets the default value for the
+:ref:`"mode" option of the Email validator <reference-constraint-email-mode>`.
 
-**type**: ``string`` **default**: ``null``
+.. _reference-validation-enable_annotations:
 
-The DSN used by the mailer. When several DSN may be used, use
-``transports`` option (see below) instead.
+enable_attributes
+.................
 
-transports
-..........
+**type**: ``boolean`` **default**: ``true``
 
-**type**: ``array``
+If this option is enabled, validation constraints can be defined using `PHP attributes`_.
 
-A :ref:`list of DSN <multiple-email-transports>` that can be used by the
-mailer. A transport name is the key and the dsn is the value.
+.. _reference-validation-enabled:
 
-message_bus
-...........
+enabled
+.......
 
-**type**: ``string`` **default**: ``null`` or default bus if Messenger component is installed
+**type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation
 
-Service identifier of the message bus to use when using the
-:doc:`Messenger component </messenger>` (e.g. ``messenger.default_bus``).
+Whether or not to enable validation support.
 
-envelope
-........
+This option will automatically be set to ``true`` when one of the child
+settings is configured.
 
-sender
-""""""
+.. _reference-validation-mapping:
 
-**type**: ``string``
+mapping
+.......
 
-The "envelope sender" which is used as the value of ``MAIL FROM`` during the
-`SMTP session`_. This value overrides any other sender set in the code.
+.. _reference-validation-mapping-paths:
 
-recipients
-""""""""""
+paths
+"""""
 
-**type**: ``array``
+**type**: ``array`` **default**: ``['config/validation/']``
 
-The "envelope recipient" which is used as the value of ``RCPT TO`` during the
-the `SMTP session`_. This value overrides any other recipient set in the code.
+This option allows to define an array of paths with files or directories where
+the component will look for additional validation files:
 
 .. configuration-block::
 
     .. code-block:: yaml
 
-        # config/packages/mailer.yaml
+        # config/packages/framework.yaml
         framework:
-            mailer:
-                dsn: 'smtp://localhost:25'
-                envelope:
-                    recipients: ['admin@symfony.com', 'lead@symfony.com']
+            validation:
+                mapping:
+                    paths:
+                        - "%kernel.project_dir%/config/validation/"
 
     .. code-block:: xml
 
-        <!-- config/packages/mailer.xml -->
+        <!-- config/packages/framework.xml -->
         <?xml version="1.0" encoding="UTF-8" ?>
         <container xmlns="http://symfony.com/schema/dic/services"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -3542,63 +3648,77 @@ the `SMTP session`_. This value overrides any other recipient set in the code.
             xsi:schemaLocation="http://symfony.com/schema/dic/services
                 https://symfony.com/schema/dic/services/services-1.0.xsd
                 http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
             <framework:config>
-                <framework:mailer dsn="smtp://localhost:25">
-                    <framework:envelope>
-                        <framework:recipient>admin@symfony.com</framework:recipient>
-                        <framework:recipient>lead@symfony.com</framework:recipient>
-                    </framework:envelope>
-                </framework:mailer>
+                <framework:validation>
+                    <framework:mapping>
+                        <framework:path>%kernel.project_dir%/config/validation/</framework:path>
+                    </framework:mapping>
+                </framework:validation>
             </framework:config>
         </container>
 
     .. code-block:: php
 
-        // config/packages/mailer.php
-        namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+        // config/packages/framework.php
+        use Symfony\Config\FrameworkConfig;
 
-        return static function (ContainerConfigurator $container): void {
-            $container->extension('framework', [
-                'mailer' => [
-                    'dsn' => 'smtp://localhost:25',
-                    'envelope' => [
-                        'recipients' => [
-                            'admin@symfony.com',
-                            'lead@symfony.com',
-                        ],
-                    ],
-                ],
-            ]);
+        return static function (FrameworkConfig $framework): void {
+            $framework->validation()
+                ->mapping()
+                    ->paths(['%kernel.project_dir%/config/validation/']);
         };
 
-.. _mailer-headers:
+.. _reference-validation-not-compromised-password:
 
-headers
-.......
+not_compromised_password
+........................
 
-**type**: ``array``
+The :doc:`NotCompromisedPassword </reference/constraints/NotCompromisedPassword>`
+constraint makes HTTP requests to a public API to check if the given password
+has been compromised in a data breach.
 
-Headers to add to emails. The key (``name`` attribute in xml format) is the
-header name and value the header value.
+static_method
+.............
 
-.. seealso::
+**type**: ``string | array`` **default**: ``['loadValidatorMetadata']``
 
-    For more information, see :ref:`Configuring Emails Globally <mailer-configure-email-globally>`
+Defines the name of the static method which is called to load the validation
+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.
 
-messenger
-~~~~~~~~~
+translation_domain
+..................
+
+**type**: ``string | false`` **default**: ``validators``
+
+The translation domain that is used when translating validation constraint
+error messages. Use false to disable translations.
+
+
+.. _reference-validation-not-compromised-password-enabled:
 
 enabled
-.......
+"""""""
 
 **type**: ``boolean`` **default**: ``true``
 
-Whether to enable or not Messenger.
+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
+continuous integration servers.
 
-.. seealso::
+endpoint
+""""""""
 
-    For more details, see the :doc:`Messenger component </messenger>`
-    documentation.
+**type**: ``string`` **default**: ``null``
+
+By default, the :doc:`NotCompromisedPassword </reference/constraints/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
+checks. It's useful for example when the Symfony application is run in an
+intranet without public access to the internet.
 
 web_link
 ~~~~~~~~
@@ -3770,125 +3890,6 @@ Defines the kind of workflow that is going to be created, which can be either
 a normal workflow or a state machine. Read :doc:`this article </workflow/workflow-and-state-machine>`
 to know their differences.
 
-.. _framework_exceptions:
-
-exceptions
-~~~~~~~~~~
-
-**type**: ``array``
-
-Defines the :ref:`log level </logging>` and HTTP status code applied to the
-exceptions that match the given exception class:
-
-.. configuration-block::
-
-    .. code-block:: yaml
-
-        # config/packages/exceptions.yaml
-        framework:
-            exceptions:
-                Symfony\Component\HttpKernel\Exception\BadRequestHttpException:
-                    log_level: 'debug'
-                    status_code: 422
-
-    .. code-block:: xml
-
-        <!-- config/packages/exceptions.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <container xmlns="http://symfony.com/schema/dic/services"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xmlns:framework="http://symfony.com/schema/dic/symfony"
-            xsi:schemaLocation="http://symfony.com/schema/dic/services
-                https://symfony.com/schema/dic/services/services-1.0.xsd
-                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
-
-            <framework:config>
-                <framework:exception
-                    class="Symfony\Component\HttpKernel\Exception\BadRequestHttpException"
-                    log-level="debug"
-                    status-code="422"
-                />
-                <!-- ... -->
-            </framework:config>
-        </container>
-
-    .. code-block:: php
-
-        // config/packages/exceptions.php
-        use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
-        use Symfony\Config\FrameworkConfig;
-
-        return static function (FrameworkConfig $framework): void {
-            $framework->exception(BadRequestHttpException::class)
-                ->logLevel('debug')
-                ->statusCode(422)
-            ;
-        };
-
-The order in which you configure exceptions is important because Symfony will
-use the configuration of the first exception that matches ``instanceof``:
-
-.. code-block:: yaml
-
-        # config/packages/exceptions.yaml
-        framework:
-            exceptions:
-                Exception:
-                    log_level: 'debug'
-                    status_code: 404
-                # The following configuration will never be used because \RuntimeException extends \Exception
-                RuntimeException:
-                    log_level: 'debug'
-                    status_code: 422
-
-You can map a status code and a set of headers to an exception thanks
-to the ``#[WithHttpStatus]`` attribute on the exception class::
-
-    namespace App\Exception;
-
-    use Symfony\Component\HttpKernel\Attribute\WithHttpStatus;
-
-    #[WithHttpStatus(422, [
-       'Retry-After' => 10,
-       'X-Custom-Header' => 'header-value',
-    ])]
-    class CustomException extends \Exception
-    {
-    }
-
-It is also possible to map a log level on a custom exception class using
-the ``#[WithLogLevel]`` attribute::
-
-    namespace App\Exception;
-
-    use Psr\Log\LogLevel;
-    use Symfony\Component\HttpKernel\Attribute\WithLogLevel;
-
-    #[WithLogLevel(LogLevel::WARNING)]
-    class CustomException extends \Exception
-    {
-    }
-
-The attributes can also be added to interfaces directly::
-
-    namespace App\Exception;
-
-    use Symfony\Component\HttpKernel\Attribute\WithHttpStatus;
-
-    #[WithHttpStatus(422)]
-    interface CustomExceptionInterface
-    {
-    }
-
-    class CustomException extends \Exception implements CustomExceptionInterface
-    {
-    }
-
-.. versionadded:: 7.1
-
-    Support to use ``#[WithHttpStatus]`` and ``#[WithLogLevel]`` attributes
-    on interfaces was introduced in Symfony 7.1.
-
 .. _`HTTP Host header attacks`: https://www.skeletonscribe.net/2013/05/practical-http-host-header-attacks.html
 .. _`Security Advisory Blog post`: https://symfony.com/blog/security-releases-symfony-2-0-24-2-1-12-2-2-5-and-2-3-3-released#cve-2013-4752-request-gethost-poisoning
 .. _`phpstorm-url-handler`: https://github.com/sanduhrs/phpstorm-url-handler

From 7c70485deecc094e84dc36d99f4eb86fc1e8fff3 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 24 Feb 2025 16:33:11 +0100
Subject: [PATCH 539/747] [Messenger] Fix some syntax issue

---
 messenger.rst | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index e4f4abf60eb..d76e2170c09 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -543,14 +543,19 @@ command with the ``--all`` option:
 
     The ``--all`` option was introduced in Symfony 7.1.
 
-The ``--keepalive`` option can be used to prevent messages from being prematurely
-redelivered during long-running processing. It marks the message as "in progress"
-and prevents it from being redelivered until the worker finishes processing it.
+Messages that take a long time to process may be redelivered prematurely because
+some transports assume that an unacknowledged message is lost. To prevent this
+issue, use the ``--keepalive`` command option to specify an interval (in seconds;
+default value = ``5``) at which the message is marked as "in progress". This prevents
+the message from being redelivered until the worker completes processing it:
+
+.. code-block:: terminal
+
+    $ php bin/console messenger:consume --keepalive
 
 .. note::
 
-    This option is only available for supported transports, which are
-    the Beanstalkd and AmazonSQS transports.
+    This option is only available for the following transports: Beanstalkd and AmazonSQS.
 
 .. versionadded:: 7.2
 
@@ -1724,10 +1729,6 @@ The transport has a number of options:
     The message time to run before it is put back in the ready queue - in
     seconds.
 
-.. versionadded:: 7.2
-
-    Keepalive support, using the ``--keepalive`` option, was added in Symfony 7.2.
-
 .. _messenger-redis-transport:
 
 Redis Transport
@@ -2050,10 +2051,6 @@ The transport has a number of options:
     FIFO queues don't support setting a delay per message, a value of ``delay: 0``
     is required in the retry strategy settings.
 
-.. versionadded:: 7.2
-
-    Keepalive support, using the `--keepalive` option, was added in Symfony 7.2.
-
 Serializing Messages
 ~~~~~~~~~~~~~~~~~~~~
 

From 159a15002ade0b3375547423890b4ddb413bde7b Mon Sep 17 00:00:00 2001
From: Yonel Ceruto <yonel.ceruto@scnd.com>
Date: Tue, 4 Mar 2025 12:12:13 -0500
Subject: [PATCH 540/747] Update nested options examples to use setOptions
 instead of setDefault

---
 components/options_resolver.rst | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/components/options_resolver.rst b/components/options_resolver.rst
index 65685106c13..5063f5b11d9 100644
--- a/components/options_resolver.rst
+++ b/components/options_resolver.rst
@@ -662,7 +662,7 @@ default value::
 
         public function configureOptions(OptionsResolver $resolver): void
         {
-            $resolver->setDefault('spool', function (OptionsResolver $spoolResolver): void {
+            $resolver->setOptions('spool', function (OptionsResolver $spoolResolver): void {
                 $spoolResolver->setDefaults([
                     'type' => 'file',
                     'path' => '/path/to/spool',
@@ -686,6 +686,16 @@ default value::
         ],
     ]);
 
+.. deprecated:: 7.3
+
+    Defining nested option via :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::setDefault`
+    was deprecated since Symfony 7.3, use the :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::setOptions`
+    instead. Allowing to define default values for prototyped options.
+
+.. versionadded:: 7.3
+
+    The :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::setOptions` was introduced in Symfony 7.3.
+
 Nested options also support required options, validation (type, value) and
 normalization of their values. If the default value of a nested option depends
 on another option defined in the parent level, add a second ``Options`` argument
@@ -698,7 +708,7 @@ to the closure to access to them::
         public function configureOptions(OptionsResolver $resolver): void
         {
             $resolver->setDefault('sandbox', false);
-            $resolver->setDefault('spool', function (OptionsResolver $spoolResolver, Options $parent): void {
+            $resolver->setOptions('spool', function (OptionsResolver $spoolResolver, Options $parent): void {
                 $spoolResolver->setDefaults([
                     'type' => $parent['sandbox'] ? 'memory' : 'file',
                     // ...
@@ -721,13 +731,13 @@ In same way, parent options can access to the nested options as normal arrays::
 
         public function configureOptions(OptionsResolver $resolver): void
         {
-            $resolver->setDefault('spool', function (OptionsResolver $spoolResolver): void {
+            $resolver->setOptions('spool', function (OptionsResolver $spoolResolver): void {
                 $spoolResolver->setDefaults([
                     'type' => 'file',
                     // ...
                 ]);
             });
-            $resolver->setDefault('profiling', function (Options $options): void {
+            $resolver->setOptions('profiling', function (Options $options): void {
                 return 'file' === $options['spool']['type'];
             });
         }
@@ -748,7 +758,7 @@ with ``host``, ``database``, ``user`` and ``password`` each.
 
 The best way to implement this is to define the ``connections`` option as prototype::
 
-    $resolver->setDefault('connections', function (OptionsResolver $connResolver): void {
+    $resolver->setOptions('connections', function (OptionsResolver $connResolver): void {
         $connResolver
             ->setPrototype(true)
             ->setRequired(['host', 'database'])

From d49a86aba3ab1fc59ff58e98b50a7f6df318df23 Mon Sep 17 00:00:00 2001
From: HypeMC <hypemc@gmail.com>
Date: Sat, 8 Mar 2025 21:34:23 +0100
Subject: [PATCH 541/747] [Messenger] Clarify keepalive implementation for each
 transport

---
 messenger.rst | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index d76e2170c09..9a5f7017097 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1729,6 +1729,13 @@ The transport has a number of options:
     The message time to run before it is put back in the ready queue - in
     seconds.
 
+The Beanstalkd transport supports the ``--keepalive`` option by using Beanstalkd's
+``touch`` command to periodically reset the job's ``ttr``.
+
+.. versionadded:: 7.2
+
+    Keepalive support was introduced in Symfony 7.2.
+
 .. _messenger-redis-transport:
 
 Redis Transport
@@ -2051,6 +2058,13 @@ The transport has a number of options:
     FIFO queues don't support setting a delay per message, a value of ``delay: 0``
     is required in the retry strategy settings.
 
+The SQS transport supports the ``--keepalive`` option by using the ``ChangeMessageVisibility``
+action to periodically update the ``VisibilityTimeout`` of the message.
+
+.. versionadded:: 7.2
+
+    Keepalive support was introduced in Symfony 7.2.
+
 Serializing Messages
 ~~~~~~~~~~~~~~~~~~~~
 

From 8b245b252fe6fd1088ea4dfe106b39786359758e Mon Sep 17 00:00:00 2001
From: HypeMC <hypemc@gmail.com>
Date: Sat, 8 Mar 2025 23:32:42 +0100
Subject: [PATCH 542/747] [FrameworkBundle] Using existing services as
 lock/semaphore resources

---
 lock.rst                              | 8 ++++++++
 reference/configuration/framework.rst | 7 ++++---
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/lock.rst b/lock.rst
index 82ec48db572..1f149466216 100644
--- a/lock.rst
+++ b/lock.rst
@@ -62,6 +62,8 @@ this behavior by using the ``lock`` key like:
             lock: 'oci:host=127.0.0.1;dbname=app'
             lock: 'mongodb://127.0.0.1/app?collection=lock'
             lock: '%env(LOCK_DSN)%'
+            # using an existing service
+            lock: 'snc_redis.default'
 
             # named locks
             lock:
@@ -119,6 +121,9 @@ this behavior by using the ``lock`` key like:
 
                     <framework:resource>%env(LOCK_DSN)%</framework:resource>
 
+                    <!-- using an existing service -->
+                    <framework:resource>snc_redis.default</framework:resource>
+
                     <!-- named locks -->
                     <framework:resource name="invoice">semaphore</framework:resource>
                     <framework:resource name="invoice">redis://r2.docker</framework:resource>
@@ -130,6 +135,7 @@ this behavior by using the ``lock`` key like:
     .. code-block:: php
 
         // config/packages/lock.php
+        use function Symfony\Component\DependencyInjection\Loader\Configurator\env;
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
@@ -152,6 +158,8 @@ this behavior by using the ``lock`` key like:
                 ->resource('default', ['oci:host=127.0.0.1;dbname=app'])
                 ->resource('default', ['mongodb://127.0.0.1/app?collection=lock'])
                 ->resource('default', [env('LOCK_DSN')])
+                // using an existing service
+                ->resource('default', ['snc_redis.default'])
 
                 // named locks
                 ->resource('invoice', ['semaphore', 'redis://r2.docker'])
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 0334b918c66..f6a275067dc 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -2048,7 +2048,7 @@ resources
 **type**: ``array``
 
 A map of lock stores to be created by the framework extension, with
-the name as key and DSN as value:
+the name as key and DSN or service id as value:
 
 .. configuration-block::
 
@@ -2725,7 +2725,7 @@ resources
 **type**: ``array``
 
 A map of semaphore stores to be created by the framework extension, with
-the name as key and DSN as value:
+the name as key and DSN or service id as value:
 
 .. configuration-block::
 
@@ -2756,11 +2756,12 @@ the name as key and DSN as value:
     .. code-block:: php
 
         // config/packages/semaphore.php
+        use function Symfony\Component\DependencyInjection\Loader\Configurator\env;
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
             $framework->semaphore()
-                ->resource('default', ['%env(SEMAPHORE_DSN)%']);
+                ->resource('default', [env('SEMAPHORE_DSN')]);
         };
 
 .. _reference-semaphore-resources-name:

From 16a923591094502c41be1fdd742bf20baf3c7ebf Mon Sep 17 00:00:00 2001
From: "Cadot.eu & Co." <97225403+cadot-eu@users.noreply.github.com>
Date: Sun, 9 Mar 2025 14:37:35 +0100
Subject: [PATCH 543/747] Error: Undefined Variable $texter

The variable $texter is not defined inside the method, so PHP will throw an "Undefined variable" error.
---
 notifier.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/notifier.rst b/notifier.rst
index 2382dfee284..d2dc225f4f0 100644
--- a/notifier.rst
+++ b/notifier.rst
@@ -759,7 +759,7 @@ Now you can send notifications to your desktop as follows::
                 sprintf('%s is a new subscriber', $user->getFullName())
             );
 
-            $texter->send($message);
+            $this->texter->send($message);
         }
     }
 

From b529b654f9859d27fafa76fb700a53a5ec255fcd Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 10 Mar 2025 09:13:55 +0100
Subject: [PATCH 544/747] [Messenger] Add a link to a class

---
 messenger.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index 918719615f4..36b3cc58ad4 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1794,7 +1794,7 @@ The Beanstalkd transport supports the ``--keepalive`` option by using Beanstalkd
     Keepalive support was introduced in Symfony 7.2.
 
 The Beanstalkd transport lets you set the priority of the messages being dispatched.
-Use the ``Symfony\Component\Messenger\Bridge\Beanstalkd\Transport\BeanstalkdPriorityStamp``
+Use the :class:``Symfony\\Component\\Messenger\\Bridge\\Beanstalkd\\Transport\\BeanstalkdPriorityStamp``
 and pass a number to specify the priority (default = ``1024``; lower numbers mean higher priority)::
 
     use App\Message\SomeMessage;

From 75d85bd6f082e700224c759ad27b33e2b6fe6e51 Mon Sep 17 00:00:00 2001
From: HypeMC <hypemc@gmail.com>
Date: Sat, 8 Mar 2025 22:16:20 +0100
Subject: [PATCH 545/747] [Messenger] Add Beanstalkd's `bury_on_reject` option

---
 messenger.rst | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index 36b3cc58ad4..c5edca9e9ed 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1775,8 +1775,13 @@ The Beanstalkd transport DSN may looks like this:
 
 The transport has a number of options:
 
-``tube_name`` (default: ``default``)
-    Name of the queue
+``bury_on_reject`` (default: ``false``)
+    When set to ``true``, rejected messages are placed into a "buried" state
+    in Beanstalkd instead of being deleted.
+
+    .. versionadded:: 7.3
+
+        The ``bury_on_reject`` option was introduced in Symfony 7.3.
 
 ``timeout`` (default: ``0``)
     Message reservation timeout - in seconds. 0 will cause the server to
@@ -1786,6 +1791,9 @@ The transport has a number of options:
     The message time to run before it is put back in the ready queue - in
     seconds.
 
+``tube_name`` (default: ``default``)
+    Name of the queue
+
 The Beanstalkd transport supports the ``--keepalive`` option by using Beanstalkd's
 ``touch`` command to periodically reset the job's ``ttr``.
 

From 9f396ee8cca51673b9a4b049c4709040431aedfe Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 10 Mar 2025 09:40:43 +0100
Subject: [PATCH 546/747] Added the missing versionadded directive

---
 lock.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lock.rst b/lock.rst
index 1f149466216..d9d57481f3d 100644
--- a/lock.rst
+++ b/lock.rst
@@ -167,6 +167,10 @@ this behavior by using the ``lock`` key like:
             ;
         };
 
+.. versionadded:: 7.2
+
+    The option to use an existing service as the lock/semaphore was introduced in Symfony 7.2.
+
 Locking a Resource
 ------------------
 

From e6c8e7cde54ca0bf7e213e5986eb894532bd8aca Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 10 Mar 2025 10:14:04 +0100
Subject: [PATCH 547/747] Minor rewords

---
 controller/error_pages.rst | 43 +++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 21 deletions(-)

diff --git a/controller/error_pages.rst b/controller/error_pages.rst
index 00a36f3b13a..96856764ece 100644
--- a/controller/error_pages.rst
+++ b/controller/error_pages.rst
@@ -337,40 +337,41 @@ time and again, you can have just one (or several) listeners deal with them.
     and takes measures like redirecting the user to the login page, logging them
     out and other things.
 
-Dumping error pages in static HTML files
+Dumping Error Pages as Static HTML Files
 ----------------------------------------
 
-When a web server cannot handle a request or when it triggers an error without
-calling the PHP application, it will return its default error pages, instead of
-rendering the errors as defined in your application (whether it's Symfony's
-default "Oops" error page or the pages you customized in your application).
+.. versionadded:: 7.3
 
-To avoid that and always have your web server rendering your application's error
-pages, you can dump each HTTP status error in a their own static HTML files:
+    The feature to dump error pages into static HTML files was introduced in Symfony 7.3.
 
-.. code-block:: terminal
+If an error occurs before reaching your Symfony application, web servers display
+their own default error pages instead of your custom ones. Dumping your application's
+error pages to static HTML ensures users always see your defined pages and improves
+performance by allowing the server to deliver errors instantly without calling
+your application.
 
-    $ php bin/console error:dump [--force] var/cache/prod/error_pages
+Symfony provides the following command to turn your error pages into static HTML files:
 
-.. note::
+.. code-block:: terminal
 
-    By default, it will dump HTML files for each HTTP status error.
-    You can restrict that to dump only some HTTP status code by passing them as
-    in the second argument of the command.
+    # the first argument is the path where the HTML files are stored
+    $ APP_ENV=prod php bin/console error:dump var/cache/prod/error_pages/
 
-Once the static pages are generated, you can now configure your web server to use
-them instead of their default error page. Here is an example configuration with
-nginx:
+    # by default, it generates the pages of all 4xx and 5xx errors, but you can
+    # pass a list of HTTP status codes to only generate those
+    $ APP_ENV=prod php bin/console error:dump var/cache/prod/error_pages/ 401 403 404 500
+
+You must also configure your web server to use these generated pages. For example,
+if you use Nginx:
 
 .. code-block:: nginx
 
     # /etc/nginx/conf.d/example.com.conf
     server {
-        # Your existing serverconfiguration
+        # Existing server configuration
         # ...
 
-
-	# Configure nginx to serve your application's error pages
+        # Serve static error pages
         error_page 400 /error_pages/400.html;
         error_page 401 /error_pages/401.html;
         # ...
@@ -378,7 +379,7 @@ nginx:
         error_page 511 /error_pages/511.html;
 
         location ^~ /error_pages/ {
-          root /path/to/your/symfony/var/cache/error_pages;
-          internal; # allows this location block to not be triggered when a user manually call these /error_pages/.* urls
+            root /path/to/your/symfony/var/cache/error_pages;
+            internal; # prevent direct URL access
         }
     }

From abdd3c97650685da796d864225572beb5d18d2fb Mon Sep 17 00:00:00 2001
From: HypeMC <hypemc@gmail.com>
Date: Sat, 8 Mar 2025 21:51:06 +0100
Subject: [PATCH 548/747] [Messenger] Keepalive support for Doctrine & Redis

---
 messenger.rst | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index c5edca9e9ed..fcd4148cf51 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -555,7 +555,7 @@ the message from being redelivered until the worker completes processing it:
 
 .. note::
 
-    This option is only available for the following transports: Beanstalkd and AmazonSQS.
+    This option is only available for the following transports: Beanstalkd, AmazonSQS, Doctrine and Redis.
 
 .. versionadded:: 7.2
 
@@ -1745,13 +1745,12 @@ in the table.
     The length of time to wait for a response when calling
     ``PDO::pgsqlGetNotify``, in milliseconds.
 
-The keepalive feature, which prevents messages from being prematurely redelivered during
-long-running processing, updates the ``delivered_at`` timestamp periodically to ensure
-the message is marked as "in progress".
+The Doctrine transport supports the ``--keepalive`` option by periodically updating
+the ``delivered_at`` timestamp to prevent the message from being redelivered.
 
 .. versionadded:: 7.3
 
-    Keepalive support, using the ``--keepalive`` option, was introduced in Symfony 7.3.
+    Keepalive support was introduced in Symfony 7.3.
 
 Beanstalkd Transport
 ~~~~~~~~~~~~~~~~~~~~
@@ -1802,7 +1801,7 @@ The Beanstalkd transport supports the ``--keepalive`` option by using Beanstalkd
     Keepalive support was introduced in Symfony 7.2.
 
 The Beanstalkd transport lets you set the priority of the messages being dispatched.
-Use the :class:``Symfony\\Component\\Messenger\\Bridge\\Beanstalkd\\Transport\\BeanstalkdPriorityStamp``
+Use the :class:``Symfony\Component\Messenger\Bridge\Beanstalkd\Transport\BeanstalkdPriorityStamp``
 and pass a number to specify the priority (default = ``1024``; lower numbers mean higher priority)::
 
     use App\Message\SomeMessage;
@@ -1951,6 +1950,13 @@ under the transport in ``messenger.yaml``:
     in your case) to avoid memory leaks. Otherwise, all messages will remain
     forever in Redis.
 
+The Redis transport supports the ``--keepalive`` option by using Redis's ``XCLAIM``
+command to periodically reset the message's idle time to zero.
+
+.. versionadded:: 7.3
+
+    Keepalive support was introduced in Symfony 7.3.
+
 In Memory Transport
 ~~~~~~~~~~~~~~~~~~~
 

From 0b9fbc1e9ea2290d4cf4016d8a833d0890fbba98 Mon Sep 17 00:00:00 2001
From: HypeMC <hypemc@gmail.com>
Date: Mon, 10 Mar 2025 15:13:28 +0100
Subject: [PATCH 549/747] [Messenger] Fix link to class

---
 messenger.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index fcd4148cf51..08209896ef4 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1801,7 +1801,7 @@ The Beanstalkd transport supports the ``--keepalive`` option by using Beanstalkd
     Keepalive support was introduced in Symfony 7.2.
 
 The Beanstalkd transport lets you set the priority of the messages being dispatched.
-Use the :class:``Symfony\Component\Messenger\Bridge\Beanstalkd\Transport\BeanstalkdPriorityStamp``
+Use the :class:`Symfony\\Component\\Messenger\\Bridge\\Beanstalkd\\Transport\\BeanstalkdPriorityStamp`
 and pass a number to specify the priority (default = ``1024``; lower numbers mean higher priority)::
 
     use App\Message\SomeMessage;

From 26c429efc1e8c4c5d0e3a6bb48c027f9b14bce26 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Mon, 10 Mar 2025 17:54:29 +0100
Subject: [PATCH 550/747] Fix build

---
 serializer/encoders.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/serializer/encoders.rst b/serializer/encoders.rst
index d5a98356156..a11daaa7bad 100644
--- a/serializer/encoders.rst
+++ b/serializer/encoders.rst
@@ -202,7 +202,7 @@ These are the options available on the :ref:`serializer context <serializer-cont
     If set to ``false``, will not wrap any value containing one of the
     following characters ( ``<``, ``>``, ``&``) in `a CDATA section`_ like
     following: ``<![CDATA[...]]>``.
-``cdata_wrapping_pattern`` (default: ````/[<>&]/````)
+``cdata_wrapping_pattern`` (default: ``/[<>&]/``)
     A regular expression pattern to determine if a value should be wrapped
     in a CDATA section.
 

From 4043a28b31023699509690db86c9952b013e5f5e Mon Sep 17 00:00:00 2001
From: HypeMC <hypemc@gmail.com>
Date: Mon, 10 Mar 2025 21:25:43 +0100
Subject: [PATCH 551/747] [FrameworkBundle] Mention the
 `property_info.with_constructor_extractor` option

---
 components/property_info.rst          |  8 ++++++++
 reference/configuration/framework.rst | 12 ++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/components/property_info.rst b/components/property_info.rst
index 0ff1768441a..10c4d161377 100644
--- a/components/property_info.rst
+++ b/components/property_info.rst
@@ -538,6 +538,8 @@ with the ``property_info`` service in the Symfony Framework::
     // Type information.
     $doctrineExtractor->getTypes($class, $property);
 
+.. _components-property-information-constructor-extractor:
+
 ConstructorExtractor
 ~~~~~~~~~~~~~~~~~~~~
 
@@ -570,6 +572,7 @@ Creating Your Own Extractors
 
 You can create your own property information extractors by creating a
 class that implements one or more of the following interfaces:
+:class:`Symfony\\Component\\PropertyInfo\\ConstructorArgumentTypeExtractorInterface`,
 :class:`Symfony\\Component\\PropertyInfo\\PropertyAccessExtractorInterface`,
 :class:`Symfony\\Component\\PropertyInfo\\PropertyDescriptionExtractorInterface`,
 :class:`Symfony\\Component\\PropertyInfo\\PropertyListExtractorInterface`,
@@ -587,6 +590,11 @@ service by defining it as a service with one or more of the following
 * ``property_info.access_extractor`` if it provides access information.
 * ``property_info.initializable_extractor`` if it provides initializable information
   (it checks if a property can be initialized through the constructor).
+* ``property_info.constructor_extractor`` if it provides type information from the constructor argument.
+
+  .. versionadded:: 7.3
+
+      The ``property_info.constructor_extractor`` tag was introduced in Symfony 7.3.
 
 .. _`PSR-1`: https://www.php-fig.org/psr/psr-1/
 .. _`phpDocumentor Reflection`: https://github.com/phpDocumentor/ReflectionDocBlock
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index f6a275067dc..528543a5178 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -2451,6 +2451,18 @@ enabled
 
 **type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation
 
+with_constructor_extractor
+..........................
+
+**type**: ``boolean`` **default**: ``false``
+
+Configures the ``property_info`` service to extract property information from the constructor arguments
+using the :ref:`ConstructorExtractor <components-property-information-constructor-extractor>`.
+
+.. versionadded:: 7.3
+
+    The ``with_constructor_extractor`` option was introduced in Symfony 7.3.
+
 rate_limiter
 ~~~~~~~~~~~~
 

From 07e3d4bef6a42a1d2020aef3c4e2bfd2a75f4f27 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 11 Mar 2025 08:40:59 +0100
Subject: [PATCH 552/747] Minor tweak

---
 security/expressions.rst | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/security/expressions.rst b/security/expressions.rst
index dce52ee74ff..a4ec02c7b84 100644
--- a/security/expressions.rst
+++ b/security/expressions.rst
@@ -215,10 +215,7 @@ returns an array of values that will be injected into the closure::
 
     class MyController extends AbstractController
     {
-        #[IsGranted(static function (
-            IsGrantedContext $context,
-            mixed $subject,
-        ) {
+        #[IsGranted(static function (IsGrantedContext $context, mixed $subject) {
             return $context->user === $subject['post']->getAuthor();
         }, subject: static function (array $args) {
             return [

From 45b7549223d54deed318d4e03a5b5fba98256dc4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Fern=C3=A1ndez?= <eliasfernandez@gmail.com>
Date: Tue, 25 Feb 2025 17:39:09 +0100
Subject: [PATCH 553/747] Add configuration to the mailer section #20641

https://github.com/symfony/symfony-docs/issues/20641
---
 mailer.rst | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/mailer.rst b/mailer.rst
index 9ab2f47c235..5baf9a5d193 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -1370,6 +1370,78 @@ key but not a certificate::
         ->toArray()
     );
 
+Signing Messages Globally
+.........................
+
+Instead of creating a signer instance for every email, you can configure a global signer
+that automatically applies to all outgoing messages. This approach reduces repetition
+and centralizes your configuration for both DKIM and S/MIME signing.
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/mailer.yaml
+        framework:
+            mailer:
+                dkim_signer:
+                    key: 'file://%kernel.project_dir%/var/certificates/dkim.pem'
+                    domain: 'symfony.com'
+                    select: 's1'
+                smime_signer:
+                    key: '%kernel.project_dir%/var/certificates/smime.key'
+                    certificate: '%kernel.project_dir%/var/certificates/smime.crt'
+                    passphrase: ''
+
+    .. code-block:: xml
+
+        <!-- config/packages/mailer.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <!-- ... -->
+            <framework:config>
+                <framework:mailer>
+                    <framework:dkim-signer>
+                        <framework:key>file://%kernel.project_dir%/var/certificates/dkim.pem</framework:key>
+                        <framework:domain>symfony.com</framework:domain>
+                        <framework:select>s1</framework:select>
+                    </framework:dkim-signer>
+                    <framework:smime-signer>
+                        <framework:key>%kernel.project_dir%/var/certificates/smime.pem</framework:key>
+                        <framework:certificate>%kernel.project_dir%/var/certificates/smime.crt</framework:certificate>
+                        <framework:passphrase></framework:passphrase>
+                    </framework:smime-signer>
+                </framework:mailer>
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/mailer.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            $mailer = $framework->mailer();
+            $mailer->dsn('%env(MAILER_DSN)%');
+            $mailer->dkimSigner()
+                    ->key('file://%kernel.project_dir%/var/certificates/dkim.pem')
+                    ->domain('symfony.com')
+                    ->select('s1');
+
+            $mailer->smimeSigner()
+                    ->key('%kernel.project_dir%/var/certificates/smime.key')
+                    ->certificate('%kernel.project_dir%/var/certificates/smime.crt')
+                    ->passphrase('')
+            ;
+        };
+
+
 Encrypting Messages
 ~~~~~~~~~~~~~~~~~~~
 
@@ -1411,6 +1483,57 @@ and it will select the appropriate certificate depending on the ``To`` option::
     $firstEncryptedEmail = $encrypter->encrypt($firstEmail);
     $secondEncryptedEmail = $encrypter->encrypt($secondEmail);
 
+
+Encrypting Messages Globally
+............................
+
+Similarly, you can avoid instantiating a new encrypter for every email by setting up a
+global S/MIME encrypter. With this configuration, the encrypter is automatically
+applied to all emails you send.
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/mailer.yaml
+        framework:
+            mailer:
+                smime_encrypter:
+                    certificate: '%kernel.project_dir%/var/certificates/smime.crt'
+
+    .. code-block:: xml
+
+        <!-- config/packages/mailer.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <!-- ... -->
+            <framework:config>
+                <framework:mailer>
+                    <framework:smime-encrypter>
+                        <framework:certificate>%kernel.project_dir%/var/certificates/smime.crt</framework:certificate>
+                    </framework:smime-encrypter>
+                </framework:mailer>
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/mailer.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            $mailer = $framework->mailer();
+            $mailer->smimeEncrypter()
+                    ->certificate('%kernel.project_dir%/var/certificates/smime.crt')
+            ;
+        };
+
 .. _multiple-email-transports:
 
 Multiple Email Transports

From ea5d2cf91db89eb0743cc72946b0b5af497a21cd Mon Sep 17 00:00:00 2001
From: Jalen Muller <jalen@jcid.nl>
Date: Tue, 11 Mar 2025 10:21:47 +0100
Subject: [PATCH 554/747] Document the `configureCssLoader` method

---
 frontend/encore/advanced-config.rst | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/frontend/encore/advanced-config.rst b/frontend/encore/advanced-config.rst
index bbd4fc44c93..2a94a4f33cf 100644
--- a/frontend/encore/advanced-config.rst
+++ b/frontend/encore/advanced-config.rst
@@ -198,6 +198,32 @@ Now you can inject your service into your class::
         $this->render($emailTwo);
     }
 
+Configuring the CSS Loader
+--------------------------
+
+Encore provides the method ``configureCssLoader()`` to configure options for ``css-loader``. This method allows you to customize how Webpack processes CSS assets.
+
+A common use case is filtering certain URLs so that Webpack does not attempt to resolve them. For example, if user-uploaded assets are stored under in a user uploaded directory, Webpack should not process these paths since they may not exist at build time.
+
+Use ``configureCssLoader()`` as follows:
+
+.. code-block:: javascript
+
+    // Configuring the CSS Loader in Webpack Encore
+    // This ensures that Webpack does not attempt to resolve certain URLs in CSS files
+
+    Encore.configureCssLoader((options) => {
+        options.url = {
+            filter: (url) => {
+                // Ignore URLs that start with /uploads/
+                if (url.startsWith('/uploads/')) {
+                    return false;
+                }
+                return true; // Process other URLs normally
+            },
+        };
+    });
+
 Generating a Webpack Configuration Object without using the Command-Line Interface
 ----------------------------------------------------------------------------------
 

From 6930b68bc3e613cf35b9402c839db0fdab563da1 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 11 Mar 2025 13:15:06 +0100
Subject: [PATCH 555/747] Minor reword

---
 mailer.rst | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index 1a6605a3fe3..f1d0a921567 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -1367,9 +1367,9 @@ key but not a certificate::
 Signing Messages Globally
 .........................
 
-Instead of creating a signer instance for every email, you can configure a global signer
-that automatically applies to all outgoing messages. This approach reduces repetition
-and centralizes your configuration for both DKIM and S/MIME signing.
+Instead of creating a signer instance for each email, you can configure a global
+signer that automatically applies to all outgoing messages. This approach
+minimizes repetition and centralizes your configuration for DKIM and S/MIME signing.
 
 .. configuration-block::
 
@@ -1435,6 +1435,9 @@ and centralizes your configuration for both DKIM and S/MIME signing.
             ;
         };
 
+.. versionadded:: 7.3
+
+    Global message signing was introduced in Symfony 7.3.
 
 Encrypting Messages
 ~~~~~~~~~~~~~~~~~~~
@@ -1477,13 +1480,11 @@ and it will select the appropriate certificate depending on the ``To`` option::
     $firstEncryptedEmail = $encrypter->encrypt($firstEmail);
     $secondEncryptedEmail = $encrypter->encrypt($secondEmail);
 
-
 Encrypting Messages Globally
 ............................
 
-Similarly, you can avoid instantiating a new encrypter for every email by setting up a
-global S/MIME encrypter. With this configuration, the encrypter is automatically
-applied to all emails you send.
+Instead of creating a new encrypter for each email, you can configure a global S/MIME
+encrypter that automatically applies to all outgoing messages:
 
 .. configuration-block::
 
@@ -1528,6 +1529,10 @@ applied to all emails you send.
             ;
         };
 
+.. versionadded:: 7.3
+
+    Global message encryption configuration was introduced in Symfony 7.3.
+
 .. _multiple-email-transports:
 
 Multiple Email Transports

From cc298b88c90d2f0b5425d9fe08bbfc73f52d6ae4 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 12 Mar 2025 09:19:37 +0100
Subject: [PATCH 556/747] Minor reword

---
 frontend/encore/advanced-config.rst | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/frontend/encore/advanced-config.rst b/frontend/encore/advanced-config.rst
index 2a94a4f33cf..b7a02883e08 100644
--- a/frontend/encore/advanced-config.rst
+++ b/frontend/encore/advanced-config.rst
@@ -201,25 +201,27 @@ Now you can inject your service into your class::
 Configuring the CSS Loader
 --------------------------
 
-Encore provides the method ``configureCssLoader()`` to configure options for ``css-loader``. This method allows you to customize how Webpack processes CSS assets.
+Encore provides the ``configureCssLoader()`` method to customize how ``css-loader``
+processes your CSS assets. One common use case is to prevent Webpack from resolving
+certain URLs.
 
-A common use case is filtering certain URLs so that Webpack does not attempt to resolve them. For example, if user-uploaded assets are stored under in a user uploaded directory, Webpack should not process these paths since they may not exist at build time.
-
-Use ``configureCssLoader()`` as follows:
+For instance, if your application serves user-uploaded assets from a specific
+directory, you'll want Webpack to ignore these paths since they may not exist
+during the build process:
 
 .. code-block:: javascript
 
     // Configuring the CSS Loader in Webpack Encore
-    // This ensures that Webpack does not attempt to resolve certain URLs in CSS files
-
+    // Prevent Webpack from resolving certain URLs in CSS files
     Encore.configureCssLoader((options) => {
         options.url = {
             filter: (url) => {
-                // Ignore URLs that start with /uploads/
+                // Ignore URLs beginning with /uploads/
                 if (url.startsWith('/uploads/')) {
                     return false;
                 }
-                return true; // Process other URLs normally
+
+                return true; // Process other URLs as usual
             },
         };
     });

From f5164f73fbebea6b6a5d40acdb7210f22b46f423 Mon Sep 17 00:00:00 2001
From: Staormin <kevin.macquer@gmail.com>
Date: Fri, 21 Feb 2025 15:20:19 +0100
Subject: [PATCH 557/747] [Messenger][Process] add fromShellCommandLine
 documentation

---
 components/process.rst |  2 ++
 messenger.rst          | 33 +++++++++++++++++++++++++++++++--
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/components/process.rst b/components/process.rst
index f6c8837d2c3..7552537e82e 100644
--- a/components/process.rst
+++ b/components/process.rst
@@ -114,6 +114,8 @@ You can configure the options passed to the ``other_options`` argument of
     and ``suppress_errors``) are only supported on Windows operating systems.
     Check out the `PHP documentation for proc_open()`_ before using them.
 
+.. _process-using-features-from-the-os-shell:
+
 Using Features From the OS Shell
 --------------------------------
 
diff --git a/messenger.rst b/messenger.rst
index 08209896ef4..6eb187af460 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2301,8 +2301,9 @@ will take care of creating a new process with the parameters you passed::
 
     class CleanUpService
     {
-        public function __construct(private readonly MessageBusInterface $bus)
-        {
+        public function __construct(
+            private readonly MessageBusInterface $bus,
+        ) {
         }
 
         public function cleanUp(): void
@@ -2313,6 +2314,34 @@ will take care of creating a new process with the parameters you passed::
         }
     }
 
+A static factory :method:`Symfony\\Component\\Process\\Messenger\\RunProcessMessage::fromShellCommandline` is also
+available if you want to use features of your shell such as redirections or pipes::
+
+    use Symfony\Component\Messenger\MessageBusInterface;
+    use Symfony\Component\Process\Messenger\RunProcessMessage;
+
+    class CleanUpService
+    {
+        public function __construct(
+            private readonly MessageBusInterface $bus,
+        ) {
+        }
+
+        public function cleanUp(): void
+        {
+            $this->bus->dispatch(RunProcessMessage::fromShellCommandline('echo "Hello World" > var/log/hello.txt'));
+
+            // ...
+        }
+    }
+
+For more information, see the
+dedicated :ref:`Using Features From the OS Shell <process-using-features-from-the-os-shell>` documentation.
+
+.. versionadded:: 7.3
+
+    The ``RunProcessMessage::fromShellCommandline()`` method was introduced in Symfony 7.3.
+
 Once handled, the handler will return a
 :class:`Symfony\\Component\\Process\\Messenger\\RunProcessContext` which
 contains many useful information such as the exit code or the output of the

From b76b19903552db25fc8adb4c6ade4078f9b8d268 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Wed, 12 Mar 2025 10:47:41 +0100
Subject: [PATCH 558/747] [TwigBridge] Add Twig field_id() form helper

---
 form/form_customization.rst  | 6 ++++++
 reference/twig_reference.rst | 1 +
 2 files changed, 7 insertions(+)

diff --git a/form/form_customization.rst b/form/form_customization.rst
index 1c23601a883..dc09aefe77d 100644
--- a/form/form_customization.rst
+++ b/form/form_customization.rst
@@ -103,6 +103,7 @@ That's why Symfony provides other Twig form helpers that render the value of
 each form field part without adding any HTML around it:
 
 * ``field_name()``
+* ``field_id()``
 * ``field_value()``
 * ``field_label()``
 * ``field_help()``
@@ -116,6 +117,7 @@ fields, so you no longer have to deal with form themes:
 
     <input
         name="{{ field_name(form.username) }}"
+        id="{{ field_id(form.username) }}"
         value="{{ field_value(form.username) }}"
         placeholder="{{ field_label(form.username) }}"
         class="form-control"
@@ -129,6 +131,10 @@ fields, so you no longer have to deal with form themes:
         {% endfor %}
     </select>
 
+.. versionadded:: 7.3
+
+    The ``field_id()`` helper was introduced in Symfony 7.3.
+
 Form Rendering Variables
 ------------------------
 
diff --git a/reference/twig_reference.rst b/reference/twig_reference.rst
index acbab2f3817..bb636c69f02 100644
--- a/reference/twig_reference.rst
+++ b/reference/twig_reference.rst
@@ -408,6 +408,7 @@ explained in the article about :doc:`customizing form rendering </form/form_cust
 * :ref:`form_row() <reference-forms-twig-row>`
 * :ref:`form_rest() <reference-forms-twig-rest>`
 * :ref:`field_name() <reference-forms-twig-field-helpers>`
+* :ref:`field_id() <reference-forms-twig-field-helpers>`
 * :ref:`field_value() <reference-forms-twig-field-helpers>`
 * :ref:`field_label() <reference-forms-twig-field-helpers>`
 * :ref:`field_help() <reference-forms-twig-field-helpers>`

From 152d436e541d7a3e9b7ffae90404562ab6d170bc Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Wed, 12 Mar 2025 11:02:05 +0100
Subject: [PATCH 559/747] [Yaml] Add the
 Yaml::DUMP_FORCE_DOUBLE_QUOTES_ON_VALUES flag to enforce double quotes around
 string values

---
 components/yaml.rst | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/components/yaml.rst b/components/yaml.rst
index 40a172f334d..09028732c0a 100644
--- a/components/yaml.rst
+++ b/components/yaml.rst
@@ -450,6 +450,23 @@ By default, digit-only array keys are dumped as integers. You can use the
     $dumped = Yaml::dump([200 => 'foo'], 2, 4, Yaml::DUMP_NUMERIC_KEY_AS_STRING);
     // '200': foo
 
+Dumping Double Quotes on Values
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, only unsafe values are double quoted. In some scenarios, quoting
+even safe values is encouraged by various inspectors. You can use the
+``DUMP_FORCE_DOUBLE_QUOTES_ON_VALUES`` flag to enforce double quotes::
+
+    $dumped = Yaml::dump(['foo' => 'bar']);
+    // foo: bar
+
+    $dumped = Yaml::dump(['foo' => 'bar'], 2, 4, Yaml::DUMP_FORCE_DOUBLE_QUOTES_ON_VALUES);
+    // foo: "bar"
+
+.. versionadded:: 7.3
+
+    The ``Yaml::DUMP_FORCE_DOUBLE_QUOTES_ON_VALUES`` flag was introduced in Symfony 7.3.
+
 Dumping Collection of Maps
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From 7214ad2bbeaf4a99b55ba34f23c349cd092eb5a6 Mon Sep 17 00:00:00 2001
From: HypeMC <hypemc@gmail.com>
Date: Wed, 12 Mar 2025 16:13:08 +0100
Subject: [PATCH 560/747] [PropertyInfo] Fix class namespace

---
 components/property_info.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/property_info.rst b/components/property_info.rst
index 10c4d161377..39019657ced 100644
--- a/components/property_info.rst
+++ b/components/property_info.rst
@@ -572,7 +572,7 @@ Creating Your Own Extractors
 
 You can create your own property information extractors by creating a
 class that implements one or more of the following interfaces:
-:class:`Symfony\\Component\\PropertyInfo\\ConstructorArgumentTypeExtractorInterface`,
+:class:`Symfony\\Component\\PropertyInfo\\Extractor\\ConstructorArgumentTypeExtractorInterface`,
 :class:`Symfony\\Component\\PropertyInfo\\PropertyAccessExtractorInterface`,
 :class:`Symfony\\Component\\PropertyInfo\\PropertyDescriptionExtractorInterface`,
 :class:`Symfony\\Component\\PropertyInfo\\PropertyListExtractorInterface`,

From 409ec0233462afb560b279d450e2a4fcdb0824ce Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 12 Mar 2025 17:37:39 +0100
Subject: [PATCH 561/747] Tweaks

---
 components/yaml.rst | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/components/yaml.rst b/components/yaml.rst
index 09028732c0a..471b59dcf5c 100644
--- a/components/yaml.rst
+++ b/components/yaml.rst
@@ -453,15 +453,19 @@ By default, digit-only array keys are dumped as integers. You can use the
 Dumping Double Quotes on Values
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-By default, only unsafe values are double quoted. In some scenarios, quoting
-even safe values is encouraged by various inspectors. You can use the
-``DUMP_FORCE_DOUBLE_QUOTES_ON_VALUES`` flag to enforce double quotes::
-
-    $dumped = Yaml::dump(['foo' => 'bar']);
-    // foo: bar
-
-    $dumped = Yaml::dump(['foo' => 'bar'], 2, 4, Yaml::DUMP_FORCE_DOUBLE_QUOTES_ON_VALUES);
-    // foo: "bar"
+By default, only unsafe string values are enclosed in double quotes (for example,
+if they are reserved words or contain newlines and spaces). Use the
+``DUMP_FORCE_DOUBLE_QUOTES_ON_VALUES`` flag to add double quotes to all string values::
+
+    $dumped = Yaml::dump([
+        'foo' => 'bar', 'some foo' => 'some bar', 'x' => 3.14, 'y' => true, 'z' => null,
+    ]);
+    // foo: bar, 'some foo': 'some bar', x: 3.14, 'y': true, z: null
+
+    $dumped = Yaml::dump([
+        'foo' => 'bar', 'some foo' => 'some bar', 'x' => 3.14, 'y' => true, 'z' => null,
+    ], 2, 4, Yaml::DUMP_FORCE_DOUBLE_QUOTES_ON_VALUES);
+    // "foo": "bar", "some foo": "some bar", "x": 3.14, "y": true, "z": null
 
 .. versionadded:: 7.3
 

From b04bc3a09b64d35fe47e5b74f01023c08584f3a1 Mon Sep 17 00:00:00 2001
From: Santiago San Martin <sanmartindev@gmail.com>
Date: Fri, 14 Mar 2025 18:47:45 -0300
Subject: [PATCH 562/747] Add new tip to explain usage of --method option for
 filtering routes

---
 routing.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/routing.rst b/routing.rst
index 4ab0dce2a82..c5cf5cd7f33 100644
--- a/routing.rst
+++ b/routing.rst
@@ -456,6 +456,10 @@ route details:
     Use the ``--show-aliases`` option to show all available aliases for a given
     route.
 
+.. tip::
+
+    Use the ``--method`` option to filter routes by HTTP method. For example, to only show routes that use the ``GET`` method, add ``--method=GET``
+
 The other command is called ``router:match`` and it shows which route will match
 the given URL. It's useful to find out why some URL is not executing the
 controller action that you expect:

From d51154b75f4e8934d4997f06a0f1e18de6871a8c Mon Sep 17 00:00:00 2001
From: HypeMC <hypemc@gmail.com>
Date: Mon, 17 Mar 2025 01:27:35 +0100
Subject: [PATCH 563/747] [Serializer] Fix `defaultContext` example

---
 serializer.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/serializer.rst b/serializer.rst
index d541310aa15..cd181787763 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -344,7 +344,7 @@ instance to disallow extra fields while deserializing:
 
         return static function (FrameworkConfig $framework): void {
             $framework->serializer()
-                ->defaultContext('', [
+                ->defaultContext([
                     'allow_extra_attributes' => false,
                 ])
             ;

From be54b38d951479d27957388da18e530cfb502209 Mon Sep 17 00:00:00 2001
From: Steven Renaux <steven.renaux@sensiolabs.com>
Date: Mon, 17 Mar 2025 13:53:23 +0100
Subject: [PATCH 564/747] Update input option for MoneyType

---
 reference/forms/types/money.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/reference/forms/types/money.rst b/reference/forms/types/money.rst
index a02b695abd4..967fe9e4ce4 100644
--- a/reference/forms/types/money.rst
+++ b/reference/forms/types/money.rst
@@ -83,6 +83,9 @@ input
 By default, the money value is converted to a ``float`` PHP type. If you need the
 value to be converted into an integer (e.g. because some library needs money
 values stored in cents as integers) set this option to ``integer``.
+You can also set this option to ``string``, it can be useful if the underlying
+data is a string for precision reasons (for example, Doctrine uses strings for
+the decimal type).
 
 .. versionadded:: 7.1
 

From b8af29ce4c629060b2f167a45afe77acac4bdf32 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 18 Mar 2025 16:04:59 +0100
Subject: [PATCH 565/747] Reword

---
 routing.rst | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/routing.rst b/routing.rst
index c5cf5cd7f33..68d6a30fc41 100644
--- a/routing.rst
+++ b/routing.rst
@@ -434,6 +434,21 @@ evaluates them:
     blog_show         ANY      ANY      ANY    /blog/{slug}
     ----------------  -------  -------  -----  --------------------------------------------
 
+    # pass this option to also display all the defined route aliases
+    $ php bin/console debug:router --show-aliases
+
+    # pass this option to only display routes that match the given HTTP method
+    # (you can use the special value ANY to see routes that match any method)
+    $ php bin/console debug:router --method=GET
+    $ php bin/console debug:router --method=ANY
+
+    # pass the option more than once to display the routes that match all the given methods
+    $ php bin/console debug:router --method=GET --method=PATCH
+
+.. versionadded:: 7.3
+
+    The ``--method`` option was introduced in Symfony 7.3.
+
 Pass the name (or part of the name) of some route to this argument to print the
 route details:
 
@@ -451,15 +466,6 @@ route details:
     |             | utf8: true                                              |
     +-------------+---------------------------------------------------------+
 
-.. tip::
-
-    Use the ``--show-aliases`` option to show all available aliases for a given
-    route.
-
-.. tip::
-
-    Use the ``--method`` option to filter routes by HTTP method. For example, to only show routes that use the ``GET`` method, add ``--method=GET``
-
 The other command is called ``router:match`` and it shows which route will match
 the given URL. It's useful to find out why some URL is not executing the
 controller action that you expect:

From 387943cee13b5c0dc01b7b85289cd46a12f2940b Mon Sep 17 00:00:00 2001
From: Maxime Doutreluingne <maxime.doutreluingne@gmail.com>
Date: Sun, 23 Feb 2025 18:45:08 +0100
Subject: [PATCH 566/747] [Validator] Allow Unique constraint validation on all
 elements

---
 reference/constraints/Unique.rst | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/reference/constraints/Unique.rst b/reference/constraints/Unique.rst
index a1be67d6f2f..a37eba30c61 100644
--- a/reference/constraints/Unique.rst
+++ b/reference/constraints/Unique.rst
@@ -216,4 +216,17 @@ trailing whitespace during validation.
 
 .. include:: /reference/constraints/_payload-option.rst.inc
 
+``stopOnFirstError``
+~~~~~~~~~~~~~~~~~~~~
+
+**type**: ``boolean`` **default**: ``true``
+
+By default, this constraint stops at the first violation. If the option is set to ``false``,
+validation will continue on all elements and return all detected
+:class:`Symfony\\Component\\Validator\\ConstraintViolation` object.
+
+.. versionadded:: 7.3
+
+    The ``stopOnFirstError`` option was introduced in Symfony 7.3.
+
 .. _`PHP callable`: https://www.php.net/callable

From 8801059a62bcc91918964f46c28142c947a40d62 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 18 Mar 2025 16:17:32 +0100
Subject: [PATCH 567/747] Minor tweak

---
 reference/constraints/Unique.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/reference/constraints/Unique.rst b/reference/constraints/Unique.rst
index a37eba30c61..9ce84139cd5 100644
--- a/reference/constraints/Unique.rst
+++ b/reference/constraints/Unique.rst
@@ -221,9 +221,9 @@ trailing whitespace during validation.
 
 **type**: ``boolean`` **default**: ``true``
 
-By default, this constraint stops at the first violation. If the option is set to ``false``,
-validation will continue on all elements and return all detected
-:class:`Symfony\\Component\\Validator\\ConstraintViolation` object.
+By default, this constraint stops at the first violation. If this option is set
+to ``false``, validation continues on all elements and returns all detected
+:class:`Symfony\\Component\\Validator\\ConstraintViolation` objects.
 
 .. versionadded:: 7.3
 

From 4213bb57c7f139451d8df44c1f6a91d07559ec5f Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Tue, 18 Mar 2025 22:26:31 +0100
Subject: [PATCH 568/747] [Serializer] Add SnakeCaseToCamelCaseNameConverter

---
 serializer.rst | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/serializer.rst b/serializer.rst
index cd181787763..bd8506cbbe3 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -1239,6 +1239,67 @@ setting the ``name_converter`` setting to
         ];
         $serializer = new Serializer($normalizers, $encoders);
 
+snake_case to CamelCase
+~~~~~~~~~~~~~~~~~~~~~~~
+
+In Symfony applications is common to use camelCase to name properties. However
+some packages can use snake_case as convention.
+
+Symfony provides a built-in name converter designed to transform between
+CamelCase and snake_cased styles during serialization and deserialization
+processes. You can use it instead of the metadata aware name converter by
+setting the ``name_converter`` setting to
+``serializer.name_converter.snake_case_to_camel_case``:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/serializer.yaml
+        framework:
+            serializer:
+                name_converter: 'serializer.name_converter.snake_case_to_camel_case'
+
+    .. code-block:: xml
+
+        <!-- config/packages/serializer.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <framework:config>
+                <framework:serializer
+                    name-converter="serializer.name_converter.snake_case_to_camel_case"
+                />
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/serializer.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            $framework->serializer()
+                ->nameConverter('serializer.name_converter.snake_case_to_camel_case')
+            ;
+        };
+
+    .. code-block:: php-standalone
+
+        use Symfony\Component\Serializer\NameConverter\SnakeCaseToCamelCaseNameConverter;
+        use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
+
+        // ...
+        $normalizers = [
+            new ObjectNormalizer(null, new SnakeCaseToCamelCaseNameConverter()),
+        ];
+        $serializer = new Serializer($normalizers, $encoders);
+
 .. _serializer-built-in-normalizers:
 
 Serializer Normalizers

From 020ef3a702bb8b173d164d40d73626dc449d559a Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Tue, 18 Mar 2025 22:56:19 +0100
Subject: [PATCH 569/747] Replace TaggedIterator and TaggedLocator by
 Au*towireIterator and AutowireLocator

---
 .../service_subscribers_locators.rst          | 20 +++++++++----------
 service_container/tags.rst                    |  2 +-
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst
index 9c6451931d1..a2aabb48901 100644
--- a/service_container/service_subscribers_locators.rst
+++ b/service_container/service_subscribers_locators.rst
@@ -270,8 +270,8 @@ the following dependency injection attributes in the ``getSubscribedServices()``
 method directly:
 
 * :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Autowire`
-* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator`
-* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator`
+* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireIterator`
+* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireLocator`
 * :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Target`
 * :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireDecorated`
 
@@ -282,8 +282,8 @@ This is done by having ``getSubscribedServices()`` return an array of
     use Psr\Container\ContainerInterface;
     use Psr\Log\LoggerInterface;
     use Symfony\Component\DependencyInjection\Attribute\Autowire;
-    use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
-    use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
+    use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
+    use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
     use Symfony\Component\DependencyInjection\Attribute\Target;
     use Symfony\Contracts\Service\Attribute\SubscribedService;
 
@@ -299,11 +299,11 @@ This is done by having ``getSubscribedServices()`` return an array of
             // Target
             new SubscribedService('event.logger', LoggerInterface::class, attributes: new Target('eventLogger')),
 
-            // TaggedIterator
-            new SubscribedService('loggers', 'iterable', attributes: new TaggedIterator('logger.tag')),
+            // AutowireIterator
+            new SubscribedService('loggers', 'iterable', attributes: new AutowireIterator('logger.tag')),
 
-            // TaggedLocator
-            new SubscribedService('handlers', ContainerInterface::class, attributes: new TaggedLocator('handler.tag')),
+            // AutowireLocator
+            new SubscribedService('handlers', ContainerInterface::class, attributes: new AutowireLocator('handler.tag')),
         ];
     }
 
@@ -975,8 +975,8 @@ You can use the ``attributes`` argument of ``SubscribedService`` to add any
 of the following dependency injection attributes:
 
 * :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Autowire`
-* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator`
-* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator`
+* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireIterator`
+* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireLocator`
 * :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Target`
 * :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireDecorated`
 
diff --git a/service_container/tags.rst b/service_container/tags.rst
index 270d6702f5a..39262fa51be 100644
--- a/service_container/tags.rst
+++ b/service_container/tags.rst
@@ -750,7 +750,7 @@ directly via PHP attributes:
 
 .. note::
 
-    Some IDEs will show an error when using ``#[TaggedIterator]`` together
+    Some IDEs will show an error when using ``#[AutowireIterator]`` together
     with the `PHP constructor promotion`_:
     *"Attribute cannot be applied to a property because it does not contain the 'Attribute::TARGET_PROPERTY' flag"*.
     The reason is that those constructor arguments are both parameters and class

From 10565283d5234c46b8ed4510d79d2d75310b2f9c Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 19 Mar 2025 08:35:26 +0100
Subject: [PATCH 570/747] Tweaks

---
 serializer.rst | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/serializer.rst b/serializer.rst
index bd8506cbbe3..54555d7b340 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -1242,12 +1242,12 @@ setting the ``name_converter`` setting to
 snake_case to CamelCase
 ~~~~~~~~~~~~~~~~~~~~~~~
 
-In Symfony applications is common to use camelCase to name properties. However
-some packages can use snake_case as convention.
+In Symfony applications, it is common to use camelCase for naming properties.
+However some packages may follow a snake_case convention.
 
 Symfony provides a built-in name converter designed to transform between
-CamelCase and snake_cased styles during serialization and deserialization
-processes. You can use it instead of the metadata aware name converter by
+CamelCase and snake_case styles during serialization and deserialization
+processes. You can use it instead of the metadata-aware name converter by
 setting the ``name_converter`` setting to
 ``serializer.name_converter.snake_case_to_camel_case``:
 
@@ -1300,6 +1300,10 @@ setting the ``name_converter`` setting to
         ];
         $serializer = new Serializer($normalizers, $encoders);
 
+.. versionadded:: 7.2
+
+    The snake_case to CamelCase converter was introduced in Symfony 7.2.
+
 .. _serializer-built-in-normalizers:
 
 Serializer Normalizers

From d009744f9140c536a5ae3b4a578f7780fb53771a Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 19 Mar 2025 09:58:18 +0100
Subject: [PATCH 571/747] Tweaks

---
 components/options_resolver.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/components/options_resolver.rst b/components/options_resolver.rst
index 5063f5b11d9..6f3a6751f28 100644
--- a/components/options_resolver.rst
+++ b/components/options_resolver.rst
@@ -688,13 +688,13 @@ default value::
 
 .. deprecated:: 7.3
 
-    Defining nested option via :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::setDefault`
-    was deprecated since Symfony 7.3, use the :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::setOptions`
-    instead. Allowing to define default values for prototyped options.
+    Defining nested options via :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::setDefault`
+    is deprecated since Symfony 7.3. Use the :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::setOptions`
+    method instead, which also allows defining default values for prototyped options.
 
 .. versionadded:: 7.3
 
-    The :method:`Symfony\\Component\\OptionsResolver\\OptionsResolver::setOptions` was introduced in Symfony 7.3.
+    The ``setOptions()`` method was introduced in Symfony 7.3.
 
 Nested options also support required options, validation (type, value) and
 normalization of their values. If the default value of a nested option depends

From 1b09d4c56c5d47cc928a49c249c5abc97457b282 Mon Sep 17 00:00:00 2001
From: HypeMC <hypemc@gmail.com>
Date: Wed, 19 Mar 2025 01:49:32 +0100
Subject: [PATCH 572/747] [Serializer] Document named serializers

---
 serializer.rst | 249 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 249 insertions(+)

diff --git a/serializer.rst b/serializer.rst
index 605946956ac..5f9144abae0 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -1537,6 +1537,255 @@ like:
             PropertyNormalizer::NORMALIZE_VISIBILITY => PropertyNormalizer::NORMALIZE_PUBLIC | PropertyNormalizer::NORMALIZE_PROTECTED,
         ]);
 
+Named Serializers
+-----------------
+
+.. versionadded:: 7.2
+
+    Named serializers were introduced in Symfony 7.2.
+
+Sometimes, you may need multiple configurations for the serializer, such
+as different default contexts, name converters, or sets of normalizers and
+encoders, depending on the use case. For example, when your application
+communicates with multiple APIs, each with its own set of rules.
+
+This can be achieved by configuring multiple instances of the serializer
+using the ``named_serializers`` option:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/serializer.yaml
+        framework:
+            serializer:
+                named_serializers:
+                    api_client1:
+                        name_converter: 'serializer.name_converter.camel_case_to_snake_case'
+                        default_context:
+                            enable_max_depth: true
+                    api_client2:
+                        default_context:
+                            enable_max_depth: false
+
+    .. code-block:: xml
+
+        <!-- config/packages/serializer.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <framework:config>
+                <framework:serializer>
+
+                    <framework:named-serializer
+                        name="api_client1"
+                        name-converter="serializer.name_converter.camel_case_to_snake_case"
+                    >
+                        <framework:default-context>
+                            <framework:enable_max_depth>true</framework:enable_max_depth>
+                        </framework:default-context>
+                    </framework:named-serializer>
+
+                    <framework:named-serializer name="api_client2">
+                        <framework:default-context>
+                            <framework:enable_max_depth>false</framework:enable_max_depth>
+                        </framework:default-context>
+                    </framework:named-serializer>
+
+                </framework:serializer>
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/serializer.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            $framework->serializer()
+                ->namedSerializer('api_client1')
+                    ->nameConverter('serializer.name_converter.camel_case_to_snake_case')
+                    ->defaultContext([
+                        'enable_max_depth' => true,
+                    ])
+            ;
+            $framework->serializer()
+                ->namedSerializer('api_client2')
+                    ->defaultContext([
+                        'enable_max_depth' => false,
+                    ])
+            ;
+        };
+
+You can inject these different serializer instances
+using :ref:`named aliases <autowiring-multiple-implementations-same-type>`::
+
+    namespace App\Controller;
+
+    // ...
+    use Symfony\Component\DependencyInjection\Attribute\Target;
+
+    class PersonController extends AbstractController
+    {
+        public function index(
+            SerializerInterface $serializer,           // Default serializer
+            SerializerInterface $apiClient1Serializer, // api_client1 serializer
+            #[Target('apiClient2.serializer')]         // api_client2 serializer
+            SerializerInterface $customName,
+        ) {
+            // ...
+        }
+    }
+
+Named serializers are configured with the default set of normalizers and encoders.
+
+You can register additional normalizers and encoders with a specific named
+serializer by adding a ``serializer`` attribute to
+the :ref:`serializer.normalizer <reference-dic-tags-serializer-normalizer>`
+or :ref:`serializer.encoder <reference-dic-tags-serializer-encoder>` tags:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/services.yaml
+        services:
+            # ...
+
+            Symfony\Component\Serializer\Normalizer\CustomNormalizer:
+                # Prevent this normalizer from automatically being included in the default serializer
+                autoconfigure: false
+                tags:
+                    # Include this normalizer in a single serializer
+                    - serializer.normalizer: { serializer: 'api_client1' }
+                    # Include this normalizer in multiple serializers
+                    - serializer.normalizer: { serializer: [ 'api_client1', 'api_client2' ] }
+                    # Include this normalizer in all serializers (including the default one)
+                    - serializer.normalizer: { serializer: '*' }
+
+    .. code-block:: xml
+
+        <!-- config/services.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd">
+
+            <services>
+                <!-- ... -->
+
+                <!-- Disable autoconfigure to prevent this normalizer from automatically -->
+                <!-- being included in the default serializer -->
+                <service
+                    id="Symfony\Component\Serializer\Normalizer\CustomNormalizer"
+                    autoconfigure="false"
+                >
+                    <!-- Include this normalizer in a single serializer -->
+                    <tag name="serializer.normalizer" serializer="api_client1"/>
+
+                    <!-- Include this normalizer in multiple serializers -->
+                    <tag name="serializer.normalizer" serializer="api_client1"/>
+                    <tag name="serializer.normalizer" serializer="api_client2"/>
+
+                    <!-- Include this normalizer in all serializers (including the default one) -->
+                    <tag name="serializer.normalizer" serializer="*"/>
+                </service>
+            </services>
+        </container>
+
+    .. code-block:: php
+
+        // config/services.php
+        namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+        use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
+
+        return function(ContainerConfigurator $container) {
+            // ...
+
+            $services->set(CustomNormalizer::class)
+                // Prevent this normalizer from automatically being included in the default serializer
+                ->autoconfigure(false)
+
+                // Include this normalizer in a single serializer
+                ->tag('serializer.normalizer', ['serializer' => 'api_client1'])
+                // Include this normalizer in multiple serializers
+                ->tag('serializer.normalizer', ['serializer' => ['api_client1', 'api_client2']])
+                // Include this normalizer in all serializers (including the default one)
+                ->tag('serializer.normalizer', ['serializer' => '*'])
+            ;
+        };
+
+When the ``serializer`` attribute is not set, the service is registered with
+the default serializer.
+
+Each normalizer and encoder used in a named serializer is tagged with
+a ``serializer.normalizer.<name>`` or ``serializer.encoder.<name>`` tag,
+which can be used to list their priorities using the following command:
+
+.. code-block:: terminal
+
+    $ php bin/console debug:container --tag serializer.<normalizer|encoder>.<name>
+
+Additionally, you can exclude the default set of normalizers and encoders by
+setting the ``include_built_in_normalizers`` and ``include_built_in_encoders``
+options to ``false``:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/serializer.yaml
+        framework:
+            serializer:
+                named_serializers:
+                    api_client1:
+                        include_built_in_normalizers: false
+                        include_built_in_encoders: true
+
+    .. code-block:: xml
+
+        <!-- config/packages/serializer.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <framework:config>
+                <framework:serializer>
+
+                    <framework:named-serializer
+                        name="api_client1"
+                        include-built-in-normalizers="false"
+                        include-built-in-encoders="true"
+                    />
+
+                </framework:serializer>
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/serializer.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            $framework->serializer()
+                ->namedSerializer('api_client1')
+                    ->includeBuiltInNormalizers(false)
+                    ->includeBuiltInEncoders(true)
+            ;
+        };
+
 Debugging the Serializer
 ------------------------
 

From fd26bacbbb4598f2f4d4f95cdd0546efe456bd58 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 20 Mar 2025 10:41:34 +0100
Subject: [PATCH 573/747] Minor tweaks

---
 messenger.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index 105bbaad8c9..6d1602f410c 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2314,8 +2314,8 @@ will take care of creating a new process with the parameters you passed::
         }
     }
 
-A static factory :method:`Symfony\\Component\\Process\\Messenger\\RunProcessMessage::fromShellCommandline` is also
-available if you want to use features of your shell such as redirections or pipes::
+If you want to use shell features such as redirections or pipes, use the static
+factory :method:Symfony\\Component\\Process\\Messenger\\RunProcessMessage::fromShellCommandline::
 
     use Symfony\Component\Messenger\MessageBusInterface;
     use Symfony\Component\Process\Messenger\RunProcessMessage;
@@ -2335,8 +2335,8 @@ available if you want to use features of your shell such as redirections or pipe
         }
     }
 
-For more information, see the
-dedicated :ref:`Using Features From the OS Shell <process-using-features-from-the-os-shell>` documentation.
+For more information, read the documentation about
+:ref:`using features from the OS shell <process-using-features-from-the-os-shell>`.
 
 .. versionadded:: 7.3
 

From 081a975430c701cff5d876f3e4d962fd794953c6 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Thu, 20 Mar 2025 21:15:48 +0100
Subject: [PATCH 574/747] [TypeInfo] Add TypeFactoryTrait::fromValue method

---
 components/type_info.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/components/type_info.rst b/components/type_info.rst
index b97fbf4cc8b..5418c765ce7 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -36,10 +36,15 @@ to the :class:`Symfony\\Component\\TypeInfo\\Type` static methods as following::
     Type::generic(Type::object(Collection::class), Type::int());
     Type::list(Type::bool());
     Type::intersection(Type::object(\Stringable::class), Type::object(\Iterator::class));
+    Type::fromValue(1.1) // same as Type::float()
 
     // Many others are available and can be
     // found in Symfony\Component\TypeInfo\TypeFactoryTrait
 
+.. versionadded:: 7.3
+
+    The ``fromValue()`` method was introduced in Symfony 7.3.
+
 Resolvers
 ~~~~~~~~~
 

From 005ad0266ce29494e1fa89df0b5fdb3596fb459f Mon Sep 17 00:00:00 2001
From: MrYamous <matt.lempereur@gmail.com>
Date: Fri, 21 Mar 2025 07:01:55 +0100
Subject: [PATCH 575/747] refer TypeFactoryTrait to github file

---
 components/type_info.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index 2a92a3db63e..3d1aa569fec 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -37,8 +37,8 @@ to the :class:`Symfony\\Component\\TypeInfo\\Type` static methods as following::
     Type::list(Type::bool());
     Type::intersection(Type::object(\Stringable::class), Type::object(\Iterator::class));
 
-    // Many others are available and can be
-    // found in Symfony\Component\TypeInfo\TypeFactoryTrait
+Many others methods are available and can be found
+in :class:`Symfony\\Component\\TypeInfo\\TypeFactoryTrait`.
 
 Resolvers
 ~~~~~~~~~

From 8967cd3617dfd0fd3be2f7f00b97b50e5f1b0060 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 21 Mar 2025 09:11:31 +0100
Subject: [PATCH 576/747] Reword

---
 components/type_info.rst | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index 5418c765ce7..25d654995e0 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -36,10 +36,12 @@ to the :class:`Symfony\\Component\\TypeInfo\\Type` static methods as following::
     Type::generic(Type::object(Collection::class), Type::int());
     Type::list(Type::bool());
     Type::intersection(Type::object(\Stringable::class), Type::object(\Iterator::class));
-    Type::fromValue(1.1) // same as Type::float()
+    // ... and more methods defined in Symfony\Component\TypeInfo\TypeFactoryTrait
 
-    // Many others are available and can be
-    // found in Symfony\Component\TypeInfo\TypeFactoryTrait
+    // you can also use a generic method that detects the type automatically
+    Type::fromValue(1.1)   // same as Type::float()
+    Type::fromValue('...') // same as Type::string()
+    Type::fromValue(false) // same as Type::false()
 
 .. versionadded:: 7.3
 

From 006b41e3f87536a2f57accf755bb8b06225bb24c Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Fri, 21 Mar 2025 09:23:37 +0100
Subject: [PATCH 577/747] Update type_info.rst

---
 components/type_info.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/components/type_info.rst b/components/type_info.rst
index 25d654995e0..7f767c1149e 100644
--- a/components/type_info.rst
+++ b/components/type_info.rst
@@ -39,9 +39,9 @@ to the :class:`Symfony\\Component\\TypeInfo\\Type` static methods as following::
     // ... and more methods defined in Symfony\Component\TypeInfo\TypeFactoryTrait
 
     // you can also use a generic method that detects the type automatically
-    Type::fromValue(1.1)   // same as Type::float()
-    Type::fromValue('...') // same as Type::string()
-    Type::fromValue(false) // same as Type::false()
+    Type::fromValue(1.1);   // same as Type::float()
+    Type::fromValue('...'); // same as Type::string()
+    Type::fromValue(false); // same as Type::false()
 
 .. versionadded:: 7.3
 

From 2243ab9246cb22dfe571f262ac30698d897b1585 Mon Sep 17 00:00:00 2001
From: Florian Cellier <florian.cellier@sensiolabs.com>
Date: Fri, 21 Mar 2025 12:37:40 +0100
Subject: [PATCH 578/747] doc: Add doc for option `--dry-run` for the command
 `importmap:require` of the AssetMapper component

---
 frontend/asset_mapper.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index d68c77c0105..2354485a2bf 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -215,6 +215,11 @@ to add any `npm package`_:
 
     $ php bin/console importmap:require bootstrap
 
+.. tip::
+
+    The command takes the well-know ``--dry-run`` option to simulate the installation of the packages, useful
+    to show what will be installed without altering anything.
+
 This adds the ``bootstrap`` package to your ``importmap.php`` file::
 
     // importmap.php

From 78eaf0d0715259cdc4c212b277861296ba552c0e Mon Sep 17 00:00:00 2001
From: Lucas Mlsna <lmlsna@gmail.com>
Date: Sat, 22 Mar 2025 23:33:16 -0500
Subject: [PATCH 579/747] Update micro_kernel_trait.rst

Yielded classes in registerBundles() function example code require "new" keyword to work.

Also removed getLogDir() and getCacheDir() functions in example code (these functions are already defined in an identical way by the parent class).
---
 configuration/micro_kernel_trait.rst | 18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/configuration/micro_kernel_trait.rst b/configuration/micro_kernel_trait.rst
index 62e8c2d4128..dbe8d1b27b9 100644
--- a/configuration/micro_kernel_trait.rst
+++ b/configuration/micro_kernel_trait.rst
@@ -260,11 +260,11 @@ Now it looks like this::
 
         public function registerBundles(): iterable
         {
-            yield FrameworkBundle();
-            yield TwigBundle();
+            yield new FrameworkBundle();
+            yield new TwigBundle();
 
             if ('dev' === $this->getEnvironment()) {
-                yield WebProfilerBundle();
+                yield new WebProfilerBundle();
             }
         }
 
@@ -305,18 +305,6 @@ Now it looks like this::
             // (use 'annotation' as the second argument if you define routes as annotations)
             $routes->import(__DIR__.'/Controller/', 'attribute');
         }
-
-        // optional, to use the standard Symfony cache directory
-        public function getCacheDir(): string
-        {
-            return __DIR__.'/../var/cache/'.$this->getEnvironment();
-        }
-
-        // optional, to use the standard Symfony logs directory
-        public function getLogDir(): string
-        {
-            return __DIR__.'/../var/log';
-        }
     }
 
 Before continuing, run this command to add support for the new dependencies:

From 0bf6bc3bd0ec2c9a806384e06b90a78fde226522 Mon Sep 17 00:00:00 2001
From: Santiago San Martin <sanmartindev@gmail.com>
Date: Sun, 23 Mar 2025 14:39:47 -0300
Subject: [PATCH 580/747] Fix documentation on router method option usage

---
 routing.rst | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/routing.rst b/routing.rst
index 68d6a30fc41..445f4a4d886 100644
--- a/routing.rst
+++ b/routing.rst
@@ -442,9 +442,6 @@ evaluates them:
     $ php bin/console debug:router --method=GET
     $ php bin/console debug:router --method=ANY
 
-    # pass the option more than once to display the routes that match all the given methods
-    $ php bin/console debug:router --method=GET --method=PATCH
-
 .. versionadded:: 7.3
 
     The ``--method`` option was introduced in Symfony 7.3.

From 2a2faa4f4689920cbade1fc1867e9f5e587794c7 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Thu, 20 Mar 2025 22:45:30 +0100
Subject: [PATCH 581/747] [HttpKernel] Support Uid in #[MapQueryParameter]

---
 controller.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/controller.rst b/controller.rst
index b33eed08360..693784885da 100644
--- a/controller.rst
+++ b/controller.rst
@@ -371,6 +371,11 @@ The ``MapQueryParameter`` attribute supports the following argument types:
 * ``float``
 * ``int``
 * ``string``
+* Objects that extend :class:`Symfony\\Component\\Uid\\AbstractUid`
+
+.. versionadded:: 7.3
+
+    The support of ``AbstractUid`` was introduced in Symfony 7.3.
 
 ``#[MapQueryParameter]`` can take an optional argument called ``filter``. You can use the
 `Validate Filters`_ constants defined in PHP::

From 996f3d374d798c1b5d76916018ba8aa9186681b5 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Thu, 20 Mar 2025 21:53:05 +0100
Subject: [PATCH 582/747] [Serializer] Add NumberNormalizer

---
 serializer.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/serializer.rst b/serializer.rst
index 7f2f7d7c2f1..18f1b06b92c 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -1387,6 +1387,14 @@ normalizers (in order of priority):
     By default, an exception is thrown when data is not a valid backed enumeration. If you
     want ``null`` instead, you can set the ``BackedEnumNormalizer::ALLOW_INVALID_VALUES`` option.
 
+:class:`Symfony\\Component\\Serializer\\Normalizer\\NumberNormalizer`
+    This normalizer converts between :phpclass:`BcMath\Number` or :phpclass:`GMP` objects and
+    strings or integers.
+
+.. versionadded:: 7.2
+
+    The ``NumberNormalizer`` was introduced in Symfony 7.2.
+
 :class:`Symfony\\Component\\Serializer\\Normalizer\\DataUriNormalizer`
     This normalizer converts between :phpclass:`SplFileInfo` objects and a
     `data URI`_ string (``data:...``) such that files can be embedded into

From e24fb9a8b3176f6b07ed23c72df57a8742610001 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Sun, 23 Mar 2025 19:19:44 +0100
Subject: [PATCH 583/747] [Scheduler] Add MessageHandler result to the
 PostRunEvent

---
 scheduler.rst | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/scheduler.rst b/scheduler.rst
index 0c6c14915c7..64a5a9f7612 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -723,10 +723,15 @@ after a message is consumed::
         $schedule = $event->getSchedule();
         $context = $event->getMessageContext();
         $message = $event->getMessage();
+        $result = $event->getResult();
 
-        // do something with the schedule, context or message
+        // do something with the schedule, context, message or result
     }
 
+.. versionadded:: 7.3
+
+    The ``getResult()`` method was introduced in Symfony 7.3.
+
 Execute this command to find out which listeners are registered for this event
 and their priorities:
 

From b67e277663beeb002583b470cd01670d4292621c Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 24 Mar 2025 09:19:44 +0100
Subject: [PATCH 584/747] Minor tweak

---
 configuration/micro_kernel_trait.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/configuration/micro_kernel_trait.rst b/configuration/micro_kernel_trait.rst
index dbe8d1b27b9..f919b1f7a74 100644
--- a/configuration/micro_kernel_trait.rst
+++ b/configuration/micro_kernel_trait.rst
@@ -305,6 +305,9 @@ Now it looks like this::
             // (use 'annotation' as the second argument if you define routes as annotations)
             $routes->import(__DIR__.'/Controller/', 'attribute');
         }
+
+        // optionally, you can define the getCacheDir() and getLogDir() methods
+        // to override the default locations for these directories
     }
 
 Before continuing, run this command to add support for the new dependencies:

From d9a48bea00bb340b407402a3f6ada1a265e5eba4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20Andr=C3=A9?= <smn.andre@gmail.com>
Date: Fri, 21 Mar 2025 03:23:02 +0100
Subject: [PATCH 585/747] [Console] Document the `TreeHelper`

---
 components/console/helpers/map.rst.inc |   1 +
 components/console/helpers/tree.rst    | 237 +++++++++++++++++++++++++
 console/style.rst                      |  26 +++
 3 files changed, 264 insertions(+)
 create mode 100644 components/console/helpers/tree.rst

diff --git a/components/console/helpers/map.rst.inc b/components/console/helpers/map.rst.inc
index 8f9ce0ca0f3..b190d1dce44 100644
--- a/components/console/helpers/map.rst.inc
+++ b/components/console/helpers/map.rst.inc
@@ -3,5 +3,6 @@
 * :doc:`/components/console/helpers/progressbar`
 * :doc:`/components/console/helpers/questionhelper`
 * :doc:`/components/console/helpers/table`
+* :doc:`/components/console/helpers/tree`
 * :doc:`/components/console/helpers/debug_formatter`
 * :doc:`/components/console/helpers/cursor`
diff --git a/components/console/helpers/tree.rst b/components/console/helpers/tree.rst
new file mode 100644
index 00000000000..2e688770c65
--- /dev/null
+++ b/components/console/helpers/tree.rst
@@ -0,0 +1,237 @@
+Tree Helper
+===========
+
+The Tree Helper allows you to build and display tree structures in the console.
+
+.. versionadded:: 7.3
+
+    The ``TreeHelper`` class was introduced in Symfony 7.3.
+
+Rendering a Tree
+----------------
+
+The :method:`Symfony\\Component\\Console\\Helper\\TreeHelper::createTree` method creates a tree structure from an array and returns a :class:`Symfony\\Component\\Console\\Helper\\Tree`
+object that can be rendered in the console.
+
+Building a Tree from an Array
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can build a tree from an array by passing the array to the :method:`Symfony\\Component\\Console\\Helper\\TreeHelper::createTree`
+method::
+
+    use Symfony\Component\Console\Helper\TreeHelper;
+
+    $tree = TreeHelper::createTree($io, null, [
+        'src' =>  [
+            'Command',
+            'Controller' => [
+                'DefaultController.php',
+            ],
+            'Kernel.php',
+        ],
+        'templates' => [
+            'base.html.twig',
+        ],
+    ]);
+
+    $tree->render();
+
+The above code will output the following tree:
+
+.. code-block:: text
+
+    ├── src
+    │   ├── Command
+    │   ├── Controller
+    │   │   └── DefaultController.php
+    │   └── Kernel.php
+    └── templates
+        └── base.html.twig
+
+Manually Creating a Tree
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can manually create a tree by creating a new instance of the :class:`Symfony\\Component\\Console\\Helper\\Tree` class and adding nodes to it::
+
+    use Symfony\Component\Console\Helper\TreeHelper;
+    use Symfony\Component\Console\Helper\TreeNode;
+
+    $node = TreeNode::fromValues([
+        'Command',
+        'Controller' => [
+            'DefaultController.php',
+        ],
+        'Kernel.php',
+    ]);
+    $node->addChild('templates');
+    $node->addChild('tests');
+
+    $tree = TreeHelper::createTree($io, $node);
+    $tree->render();
+
+Customizing the Tree Style
+--------------------------
+
+Built-in Tree Styles
+~~~~~~~~~~~~~~~~~~~~
+
+The tree helper provides a few built-in styles that you can use to customize the output of the tree.
+
+:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::default`
+
+    .. code-block:: text
+
+        ├── config
+        │   ├── packages
+        │   └── routes
+        │      ├── framework.yaml
+        │      └── web_profiler.yaml
+        ├── src
+        │   ├── Command
+        │   ├── Controller
+        │   │   └── DefaultController.php
+        │   └── Kernel.php
+        └── templates
+           └── base.html.twig
+
+:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::box`
+
+    .. code-block:: text
+
+        ┃╸ config
+        ┃  ┃╸ packages
+        ┃  ┗╸ routes
+        ┃     ┃╸ framework.yaml
+        ┃     ┗╸ web_profiler.yaml
+        ┃╸ src
+        ┃  ┃╸ Command
+        ┃  ┃╸ Controller
+        ┃  ┃  ┗╸ DefaultController.php
+        ┃  ┗╸ Kernel.php
+        ┗╸ templates
+           ┗╸ base.html.twig
+
+:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::doubleBox`
+
+    .. code-block:: text
+
+        ╠═ config
+        ║  ╠═ packages
+        ║  ╚═ routes
+        ║    ╠═ framework.yaml
+        ║    ╚═ web_profiler.yaml
+        ╠═ src
+        ║  ╠═ Command
+        ║  ╠═ Controller
+        ║  ║  ╚═ DefaultController.php
+        ║  ╚═ Kernel.php
+        ╚═ templates
+          ╚═ base.html.twig
+
+:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::compact`
+
+    .. code-block:: text
+
+        ├ config
+        │ ├ packages
+        │ └ routes
+        │   ├ framework.yaml
+        │   └ web_profiler.yaml
+        ├ src
+        │ ├ Command
+        │ ├ Controller
+        │ │ └ DefaultController.php
+        │ └ Kernel.php
+        └ templates
+          └ base.html.twig
+
+:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::light`
+
+    .. code-block:: text
+
+        |-- config
+        |   |-- packages
+        |   `-- routes
+        |       |-- framework.yaml
+        |       `-- web_profiler.yaml
+        |-- src
+        |   |-- Command
+        |   |-- Controller
+        |   |   `-- DefaultController.php
+        |   `-- Kernel.php
+        `-- templates
+            `-- base.html.twig
+
+:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::minimal`
+
+    .. code-block:: text
+
+        . config
+        . . packages
+        . . routes
+        .   . framework.yaml
+        .   . web_profiler.yaml
+        . src
+        . . Command
+        . . Controller
+        . . . DefaultController.php
+        . . Kernel.php
+        . templates
+          . base.html.twig
+
+:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::rounded`
+
+    .. code-block:: text
+
+        ├─ config
+        │  ├─ packages
+        │  ╰─ routes
+        │     ├─ framework.yaml
+        │     ╰─ web_profiler.yaml
+        ├─ src
+        │  ├─ Command
+        │  ├─ Controller
+        │  │  ╰─ DefaultController.php
+        │  ╰─ Kernel.php
+        ╰─ templates
+           ╰─ base.html.twig
+
+Making a Custom Tree Style
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can create your own tree style by passing the characters to the constructor
+of the :class:`Symfony\\Component\\Console\\Helper\\TreeStyle` class::
+
+    use Symfony\Component\Console\Helper\TreeHelper;
+    use Symfony\Component\Console\Helper\TreeStyle;
+
+    $customStyle = new TreeStyle('🟣 ', '🟠 ', '🔵 ', '🟢 ', '🔴 ', '🟡 ');
+
+    // Pass the custom style to the createTree method
+
+    $tree = TreeHelper::createTree($io, null, [
+        'src' =>  [
+            'Command',
+            'Controller' => [
+                'DefaultController.php',
+            ],
+            'Kernel.php',
+        ],
+        'templates' => [
+            'base.html.twig',
+        ],
+    ], $customStyle);
+
+    $tree->render();
+
+The above code will output the following tree:
+
+.. code-block:: text
+
+    🔵 🟣 🟡 src
+    🔵 🟢 🟣 🟡 Command
+    🔵 🟢 🟣 🟡 Controller
+    🔵 🟢 🟢 🟠 🟡 DefaultController.php
+    🔵 🟢 🟠 🟡 Kernel.php
+    🔵 🟠 🟡 templates
+    🔵 🔴 🟠 🟡 base.html.twig
diff --git a/console/style.rst b/console/style.rst
index 0aaaa3f675e..e1e5df38ffe 100644
--- a/console/style.rst
+++ b/console/style.rst
@@ -169,6 +169,32 @@ Content Methods
     styled according to the Symfony Style Guide, which allows you to use
     features such as dynamically appending rows.
 
+:method:`Symfony\\Component\\Console\\Style\\SymfonyStyle::tree`
+    It displays the given nested array as a formatted directory/file tree
+    structure in the console output::
+
+        $io->tree([
+            'src' =>  [
+                'Controller' => [
+                    'DefaultController.php',
+                ],
+                'Kernel.php',
+            ],
+            'templates' => [
+                'base.html.twig',
+            ],
+        ]);
+
+.. versionadded:: 7.3
+
+    The ``SymfonyStyle::tree()`` and the ``SymfonyStyle::createTree()`` methods
+    were introduced in Symfony 7.3.
+
+:method:`Symfony\\Component\\Console\\Style\\SymfonyStyle::createTree`
+    Creates an instance of :class:`Symfony\\Component\\Console\\Helper\\TreeHelper`
+    styled according to the Symfony Style Guide, which allows you to use
+    features such as dynamically nesting nodes.
+
 :method:`Symfony\\Component\\Console\\Style\\SymfonyStyle::newLine`
     It displays a blank line in the command output. Although it may seem useful,
     most of the times you won't need it at all. The reason is that every helper

From a0758ac62303e037fb903ba59fe807fd798f561d Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 24 Mar 2025 09:52:46 +0100
Subject: [PATCH 586/747] Tweaks

---
 components/console/helpers/tree.rst | 86 +++++++++++++++++++++++------
 1 file changed, 68 insertions(+), 18 deletions(-)

diff --git a/components/console/helpers/tree.rst b/components/console/helpers/tree.rst
index 2e688770c65..4203f8bc790 100644
--- a/components/console/helpers/tree.rst
+++ b/components/console/helpers/tree.rst
@@ -2,6 +2,8 @@ Tree Helper
 ===========
 
 The Tree Helper allows you to build and display tree structures in the console.
+It's commonly used to render directory hierarchies, but you can also use it to render
+any tree-like content, such us organizational charts, product category trees, taxonomies, etc.
 
 .. versionadded:: 7.3
 
@@ -10,16 +12,62 @@ The Tree Helper allows you to build and display tree structures in the console.
 Rendering a Tree
 ----------------
 
-The :method:`Symfony\\Component\\Console\\Helper\\TreeHelper::createTree` method creates a tree structure from an array and returns a :class:`Symfony\\Component\\Console\\Helper\\Tree`
+The :method:`Symfony\\Component\\Console\\Helper\\TreeHelper::createTree` method
+creates a tree structure from an array and returns a :class:`Symfony\\Component\\Console\\Helper\\Tree`
 object that can be rendered in the console.
 
-Building a Tree from an Array
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Rendering a Tree from an Array
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can build a tree from an array by passing the array to the
+:method:`Symfony\\Component\\Console\\Helper\\TreeHelper::createTree` method
+inside your console command::
 
-You can build a tree from an array by passing the array to the :method:`Symfony\\Component\\Console\\Helper\\TreeHelper::createTree`
-method::
+    namespace App\Command;
 
+    use Symfony\Component\Console\Attribute\AsCommand;
+    use Symfony\Component\Console\Command\Command;
+    use Symfony\Component\Console\Input\InputInterface;
+    use Symfony\Component\Console\Output\OutputInterface;
+    use Symfony\Component\Console\Style\SymfonyStyle;
     use Symfony\Component\Console\Helper\TreeHelper;
+    use Symfony\Component\Console\Helper\TreeNode;
+
+    #[AsCommand(name: 'app:some-command', description: '...')]
+    class SomeCommand extends Command
+    {
+        // ...
+
+        protected function execute(InputInterface $input, OutputInterface $output): int
+        {
+            $io = new SymfonyStyle($input, $output);
+
+            $node = TreeNode::fromValues([
+                'config/',
+                'public/',
+                'src/',
+                'templates/',
+                'tests/',
+            ]);
+
+            $tree = TreeHelper::createTree($io, $node);
+            $tree->render();
+
+            // ...
+        }
+    }
+
+This exampe would output the following:
+
+.. code-block:: terminal
+
+    ├── config/
+    ├── public/
+    ├── src/
+    ├── templates/
+    └── tests/
+
+The given contents can be defined in a multi-dimensional array:
 
     $tree = TreeHelper::createTree($io, null, [
         'src' =>  [
@@ -38,7 +86,7 @@ method::
 
 The above code will output the following tree:
 
-.. code-block:: text
+.. code-block:: terminal
 
     ├── src
     │   ├── Command
@@ -48,10 +96,11 @@ The above code will output the following tree:
     └── templates
         └── base.html.twig
 
-Manually Creating a Tree
-~~~~~~~~~~~~~~~~~~~~~~~~
+Building and Rendering a Tree
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-You can manually create a tree by creating a new instance of the :class:`Symfony\\Component\\Console\\Helper\\Tree` class and adding nodes to it::
+You can build a tree by creating a new instance of the
+:class:`Symfony\\Component\\Console\\Helper\\Tree` class and adding nodes to it::
 
     use Symfony\Component\Console\Helper\TreeHelper;
     use Symfony\Component\Console\Helper\TreeNode;
@@ -75,11 +124,12 @@ Customizing the Tree Style
 Built-in Tree Styles
 ~~~~~~~~~~~~~~~~~~~~
 
-The tree helper provides a few built-in styles that you can use to customize the output of the tree.
+The tree helper provides a few built-in styles that you can use to customize the
+output of the tree.
 
 :method:`Symfony\\Component\\Console\\Helper\\TreeStyle::default`
 
-    .. code-block:: text
+    .. code-block:: terminal
 
         ├── config
         │   ├── packages
@@ -96,7 +146,7 @@ The tree helper provides a few built-in styles that you can use to customize the
 
 :method:`Symfony\\Component\\Console\\Helper\\TreeStyle::box`
 
-    .. code-block:: text
+    .. code-block:: terminal
 
         ┃╸ config
         ┃  ┃╸ packages
@@ -113,7 +163,7 @@ The tree helper provides a few built-in styles that you can use to customize the
 
 :method:`Symfony\\Component\\Console\\Helper\\TreeStyle::doubleBox`
 
-    .. code-block:: text
+    .. code-block:: terminal
 
         ╠═ config
         ║  ╠═ packages
@@ -130,7 +180,7 @@ The tree helper provides a few built-in styles that you can use to customize the
 
 :method:`Symfony\\Component\\Console\\Helper\\TreeStyle::compact`
 
-    .. code-block:: text
+    .. code-block:: terminal
 
         ├ config
         │ ├ packages
@@ -147,7 +197,7 @@ The tree helper provides a few built-in styles that you can use to customize the
 
 :method:`Symfony\\Component\\Console\\Helper\\TreeStyle::light`
 
-    .. code-block:: text
+    .. code-block:: terminal
 
         |-- config
         |   |-- packages
@@ -164,7 +214,7 @@ The tree helper provides a few built-in styles that you can use to customize the
 
 :method:`Symfony\\Component\\Console\\Helper\\TreeStyle::minimal`
 
-    .. code-block:: text
+    .. code-block:: terminal
 
         . config
         . . packages
@@ -181,7 +231,7 @@ The tree helper provides a few built-in styles that you can use to customize the
 
 :method:`Symfony\\Component\\Console\\Helper\\TreeStyle::rounded`
 
-    .. code-block:: text
+    .. code-block:: terminal
 
         ├─ config
         │  ├─ packages
@@ -226,7 +276,7 @@ of the :class:`Symfony\\Component\\Console\\Helper\\TreeStyle` class::
 
 The above code will output the following tree:
 
-.. code-block:: text
+.. code-block:: terminal
 
     🔵 🟣 🟡 src
     🔵 🟢 🟣 🟡 Command

From 16861e3df96cedc24460d3a134c34e7278ac8624 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@open.de>
Date: Mon, 24 Mar 2025 13:14:22 +0100
Subject: [PATCH 587/747] order use statements alphabetically

---
 components/console/helpers/tree.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/components/console/helpers/tree.rst b/components/console/helpers/tree.rst
index 4203f8bc790..ae0c24ff01f 100644
--- a/components/console/helpers/tree.rst
+++ b/components/console/helpers/tree.rst
@@ -27,11 +27,11 @@ inside your console command::
 
     use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Command\Command;
+    use Symfony\Component\Console\Helper\TreeHelper;
+    use Symfony\Component\Console\Helper\TreeNode;
     use Symfony\Component\Console\Input\InputInterface;
     use Symfony\Component\Console\Output\OutputInterface;
     use Symfony\Component\Console\Style\SymfonyStyle;
-    use Symfony\Component\Console\Helper\TreeHelper;
-    use Symfony\Component\Console\Helper\TreeNode;
 
     #[AsCommand(name: 'app:some-command', description: '...')]
     class SomeCommand extends Command

From bdca4e901550d29fd3ec5c38adb02365459b1460 Mon Sep 17 00:00:00 2001
From: Arnaud De Abreu <arnaud.deabreu@nodelia.com>
Date: Mon, 24 Mar 2025 09:25:46 +0100
Subject: [PATCH 588/747] [Messenger] Add `--class-filter` option to the
 `messenger:failed:remove` command

---
 messenger.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index 6d1602f410c..8632ebdb4e0 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1312,6 +1312,9 @@ to retry them:
     # remove all messages in the failure transport
     $ php bin/console messenger:failed:remove --all
 
+    # remove only MyClass messages
+    $ php bin/console messenger:failed:remove --class-filter='MyClass'
+
 If the message fails again, it will be re-sent back to the failure transport
 due to the normal :ref:`retry rules <messenger-retries-failures>`. Once the max
 retry has been hit, the message will be discarded permanently.
@@ -1321,6 +1324,11 @@ retry has been hit, the message will be discarded permanently.
     The option to skip a message in the ``messenger:failed:retry`` command was
     introduced in Symfony 7.2
 
+.. versionadded:: 7.3
+
+    The option to filter by a message class in the ``messenger:failed:remove`` command was
+    introduced in Symfony 7.3
+
 Multiple Failed Transports
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From da62e32f9693a21f4b3130110abf6c8e2c6beab1 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Mon, 24 Mar 2025 13:56:01 +0100
Subject: [PATCH 589/747] minor

---
 messenger.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index 8632ebdb4e0..cbd79784555 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1313,7 +1313,7 @@ to retry them:
     $ php bin/console messenger:failed:remove --all
 
     # remove only MyClass messages
-    $ php bin/console messenger:failed:remove --class-filter='MyClass'
+    $ php bin/console messenger:failed:remove --class-filter='App\Message\MyMessage'
 
 If the message fails again, it will be re-sent back to the failure transport
 due to the normal :ref:`retry rules <messenger-retries-failures>`. Once the max

From 137134ad97da5b2fecc4a61027c1701c50d9faff Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Mon, 24 Mar 2025 13:57:13 +0100
Subject: [PATCH 590/747] minor

---
 messenger.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index 59f2aa0cc19..0f1eba49a9f 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1312,7 +1312,7 @@ to retry them:
     # remove all messages in the failure transport
     $ php bin/console messenger:failed:remove --all
 
-    # remove only MyClass messages
+    # remove only App\Message\MyMessage messages
     $ php bin/console messenger:failed:remove --class-filter='App\Message\MyMessage'
 
 If the message fails again, it will be re-sent back to the failure transport

From bc3412b33493e9a2d03a189f073a863f6030e909 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 24 Mar 2025 15:23:03 +0100
Subject: [PATCH 591/747] Fix syntax issue

---
 serializer.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/serializer.rst b/serializer.rst
index 18f1b06b92c..7b42ea9485c 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -1388,7 +1388,7 @@ normalizers (in order of priority):
     want ``null`` instead, you can set the ``BackedEnumNormalizer::ALLOW_INVALID_VALUES`` option.
 
 :class:`Symfony\\Component\\Serializer\\Normalizer\\NumberNormalizer`
-    This normalizer converts between :phpclass:`BcMath\Number` or :phpclass:`GMP` objects and
+    This normalizer converts between :phpclass:`BcMath\\Number` or :phpclass:`GMP` objects and
     strings or integers.
 
 .. versionadded:: 7.2

From c018ddc9c619c68c09551e21d5d4fa86d028a71f Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 24 Mar 2025 16:01:48 +0100
Subject: [PATCH 592/747] Minor tweak

---
 controller.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/controller.rst b/controller.rst
index 693784885da..05abdaee4ea 100644
--- a/controller.rst
+++ b/controller.rst
@@ -375,7 +375,7 @@ The ``MapQueryParameter`` attribute supports the following argument types:
 
 .. versionadded:: 7.3
 
-    The support of ``AbstractUid`` was introduced in Symfony 7.3.
+    Support for ``AbstractUid`` objects was introduced in Symfony 7.3.
 
 ``#[MapQueryParameter]`` can take an optional argument called ``filter``. You can use the
 `Validate Filters`_ constants defined in PHP::

From ce6c3a9992c30ddef1cd27a7c1a31b81625dc939 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 24 Mar 2025 17:09:08 +0100
Subject: [PATCH 593/747] Reword

---
 frontend/asset_mapper.rst | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index 2354485a2bf..8b27cd8ba16 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -217,8 +217,12 @@ to add any `npm package`_:
 
 .. tip::
 
-    The command takes the well-know ``--dry-run`` option to simulate the installation of the packages, useful
-    to show what will be installed without altering anything.
+    Add the ``--dry-run`` option to simulate package installation without actually
+    making any changes (e.g. ``php bin/console importmap:require bootstrap --dry-run``)
+
+    .. versionadded:: 7.3
+
+        The ``--dry-run`` option was introduced in Symfony 7.3.
 
 This adds the ``bootstrap`` package to your ``importmap.php`` file::
 

From 0dd6f3462e07172e8d8f7825ef0d175b62b74d85 Mon Sep 17 00:00:00 2001
From: Massimiliano Arione <garakkio@gmail.com>
Date: Mon, 24 Mar 2025 17:52:45 +0100
Subject: [PATCH 594/747] document DatePointType

---
 components/clock.rst | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/components/clock.rst b/components/clock.rst
index 5b20e6000b9..e1a631a9548 100644
--- a/components/clock.rst
+++ b/components/clock.rst
@@ -269,6 +269,31 @@ timestamps::
 
 .. _clock_writing-tests:
 
+Storing DatePoints in Databases
+-------------------------------
+
+If you :doc:`use Doctrine </doctrine>`, consider using the ``date_point`` Doctrine
+type, which converts to/from ``DatePoint`` objects automatically::
+
+    // src/Entity/Product.php
+    namespace App\Entity;
+
+    use Doctrine\ORM\Mapping as ORM;
+    use Symfony\Component\Clock\DatePoint;
+
+    #[ORM\Entity]
+    class Product
+    {
+        #[ORM\Column]
+        private DatePoint $created;
+
+        // ...
+    }
+
+.. versionadded:: 7.3
+
+    The `DatePointType` was introduced in Symfony 7.3.
+
 Writing Time-Sensitive Tests
 ----------------------------
 

From 823c8432df0cd3ddd685e023ea863ab4051b71f9 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 25 Mar 2025 09:58:07 +0100
Subject: [PATCH 595/747] Minor tweaks

---
 components/clock.rst | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/components/clock.rst b/components/clock.rst
index e1a631a9548..c4ac88e9092 100644
--- a/components/clock.rst
+++ b/components/clock.rst
@@ -267,13 +267,11 @@ timestamps::
     :method:`Symfony\\Component\\Clock\\DatePoint::getMicrosecond` methods were
     introduced in Symfony 7.1.
 
-.. _clock_writing-tests:
-
-Storing DatePoints in Databases
--------------------------------
+Storing DatePoints in the Database
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-If you :doc:`use Doctrine </doctrine>`, consider using the ``date_point`` Doctrine
-type, which converts to/from ``DatePoint`` objects automatically::
+If you :doc:`use Doctrine </doctrine>` to work with databases, consider using the
+``date_point`` Doctrine type, which converts to/from ``DatePoint`` objects automatically::
 
     // src/Entity/Product.php
     namespace App\Entity;
@@ -284,15 +282,22 @@ type, which converts to/from ``DatePoint`` objects automatically::
     #[ORM\Entity]
     class Product
     {
+        // if you don't define the Doctrine type explicitly, Symfony will autodetect it:
         #[ORM\Column]
-        private DatePoint $created;
+        private DatePoint $createdAt;
+
+        // if you prefer to define the Doctrine type explicitly:
+        #[ORM\Column(type: 'date_point')]
+        private DatePoint $updatedAt;
 
         // ...
     }
 
 .. versionadded:: 7.3
 
-    The `DatePointType` was introduced in Symfony 7.3.
+    The ``DatePointType`` was introduced in Symfony 7.3.
+
+.. _clock_writing-tests:
 
 Writing Time-Sensitive Tests
 ----------------------------

From 5844ee66a68c19bbcff3f7300756ed1df31c4c3a Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 25 Mar 2025 16:39:30 +0100
Subject: [PATCH 596/747] [Console] Tweak the tree helper

---
 components/console/helpers/tree.rst | 250 ++++++++++++++--------------
 1 file changed, 129 insertions(+), 121 deletions(-)

diff --git a/components/console/helpers/tree.rst b/components/console/helpers/tree.rst
index ae0c24ff01f..1161d00e942 100644
--- a/components/console/helpers/tree.rst
+++ b/components/console/helpers/tree.rst
@@ -67,7 +67,7 @@ This exampe would output the following:
     ├── templates/
     └── tests/
 
-The given contents can be defined in a multi-dimensional array:
+The given contents can be defined in a multi-dimensional array::
 
     $tree = TreeHelper::createTree($io, null, [
         'src' =>  [
@@ -125,126 +125,132 @@ Built-in Tree Styles
 ~~~~~~~~~~~~~~~~~~~~
 
 The tree helper provides a few built-in styles that you can use to customize the
-output of the tree.
-
-:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::default`
-
-    .. code-block:: terminal
-
-        ├── config
-        │   ├── packages
-        │   └── routes
-        │      ├── framework.yaml
-        │      └── web_profiler.yaml
-        ├── src
-        │   ├── Command
-        │   ├── Controller
-        │   │   └── DefaultController.php
-        │   └── Kernel.php
-        └── templates
-           └── base.html.twig
-
-:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::box`
-
-    .. code-block:: terminal
-
-        ┃╸ config
-        ┃  ┃╸ packages
-        ┃  ┗╸ routes
-        ┃     ┃╸ framework.yaml
-        ┃     ┗╸ web_profiler.yaml
-        ┃╸ src
-        ┃  ┃╸ Command
-        ┃  ┃╸ Controller
-        ┃  ┃  ┗╸ DefaultController.php
-        ┃  ┗╸ Kernel.php
-        ┗╸ templates
-           ┗╸ base.html.twig
-
-:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::doubleBox`
-
-    .. code-block:: terminal
-
-        ╠═ config
-        ║  ╠═ packages
-        ║  ╚═ routes
-        ║    ╠═ framework.yaml
-        ║    ╚═ web_profiler.yaml
-        ╠═ src
-        ║  ╠═ Command
-        ║  ╠═ Controller
-        ║  ║  ╚═ DefaultController.php
-        ║  ╚═ Kernel.php
-        ╚═ templates
-          ╚═ base.html.twig
-
-:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::compact`
-
-    .. code-block:: terminal
-
-        ├ config
-        │ ├ packages
-        │ └ routes
-        │   ├ framework.yaml
-        │   └ web_profiler.yaml
-        ├ src
-        │ ├ Command
-        │ ├ Controller
-        │ │ └ DefaultController.php
-        │ └ Kernel.php
-        └ templates
-          └ base.html.twig
-
-:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::light`
-
-    .. code-block:: terminal
-
-        |-- config
-        |   |-- packages
-        |   `-- routes
-        |       |-- framework.yaml
-        |       `-- web_profiler.yaml
-        |-- src
-        |   |-- Command
-        |   |-- Controller
-        |   |   `-- DefaultController.php
-        |   `-- Kernel.php
-        `-- templates
-            `-- base.html.twig
-
-:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::minimal`
-
-    .. code-block:: terminal
-
-        . config
-        . . packages
-        . . routes
-        .   . framework.yaml
-        .   . web_profiler.yaml
-        . src
-        . . Command
-        . . Controller
-        . . . DefaultController.php
-        . . Kernel.php
-        . templates
-          . base.html.twig
-
-:method:`Symfony\\Component\\Console\\Helper\\TreeStyle::rounded`
-
-    .. code-block:: terminal
-
-        ├─ config
-        │  ├─ packages
-        │  ╰─ routes
-        │     ├─ framework.yaml
-        │     ╰─ web_profiler.yaml
-        ├─ src
-        │  ├─ Command
-        │  ├─ Controller
-        │  │  ╰─ DefaultController.php
-        │  ╰─ Kernel.php
-        ╰─ templates
-           ╰─ base.html.twig
+output of the tree::
+
+    use Symfony\Component\Console\Helper\TreeStyle;
+    // ...
+
+    $tree = TreeHelper::createTree($io, $node, [], TreeStyle::compact());
+    $tree->render();
+
+``TreeHelper::createTree($io, $node, [], TreeStyle::default())`` (`details`_)
+
+.. code-block:: terminal
+
+    ├── config
+    │   ├── packages
+    │   └── routes
+    │      ├── framework.yaml
+    │      └── web_profiler.yaml
+    ├── src
+    │   ├── Command
+    │   ├── Controller
+    │   │   └── DefaultController.php
+    │   └── Kernel.php
+    └── templates
+       └── base.html.twig
+
+``TreeHelper::createTree($io, $node, [], TreeStyle::box())`` (`details`_)
+
+.. code-block:: terminal
+
+    ┃╸ config
+    ┃  ┃╸ packages
+    ┃  ┗╸ routes
+    ┃     ┃╸ framework.yaml
+    ┃     ┗╸ web_profiler.yaml
+    ┃╸ src
+    ┃  ┃╸ Command
+    ┃  ┃╸ Controller
+    ┃  ┃  ┗╸ DefaultController.php
+    ┃  ┗╸ Kernel.php
+    ┗╸ templates
+       ┗╸ base.html.twig
+
+``TreeHelper::createTree($io, $node, [], TreeStyle::doubleBox())`` (`details`_)
+
+.. code-block:: terminal
+
+    ╠═ config
+    ║  ╠═ packages
+    ║  ╚═ routes
+    ║    ╠═ framework.yaml
+    ║    ╚═ web_profiler.yaml
+    ╠═ src
+    ║  ╠═ Command
+    ║  ╠═ Controller
+    ║  ║  ╚═ DefaultController.php
+    ║  ╚═ Kernel.php
+    ╚═ templates
+      ╚═ base.html.twig
+
+``TreeHelper::createTree($io, $node, [], TreeStyle::compact())`` (`details`_)
+
+.. code-block:: terminal
+
+    ├ config
+    │ ├ packages
+    │ └ routes
+    │   ├ framework.yaml
+    │   └ web_profiler.yaml
+    ├ src
+    │ ├ Command
+    │ ├ Controller
+    │ │ └ DefaultController.php
+    │ └ Kernel.php
+    └ templates
+      └ base.html.twig
+
+``TreeHelper::createTree($io, $node, [], TreeStyle::light())`` (`details`_)
+
+.. code-block:: terminal
+
+    |-- config
+    |   |-- packages
+    |   `-- routes
+    |       |-- framework.yaml
+    |       `-- web_profiler.yaml
+    |-- src
+    |   |-- Command
+    |   |-- Controller
+    |   |   `-- DefaultController.php
+    |   `-- Kernel.php
+    `-- templates
+        `-- base.html.twig
+
+``TreeHelper::createTree($io, $node, [], TreeStyle::minimal())`` (`details`_)
+
+.. code-block:: terminal
+
+    . config
+    . . packages
+    . . routes
+    .   . framework.yaml
+    .   . web_profiler.yaml
+    . src
+    . . Command
+    . . Controller
+    . . . DefaultController.php
+    . . Kernel.php
+    . templates
+      . base.html.twig
+
+``TreeHelper::createTree($io, $node, [], TreeStyle::rounded())`` (`details`_)
+
+.. code-block:: terminal
+
+    ├─ config
+    │  ├─ packages
+    │  ╰─ routes
+    │     ├─ framework.yaml
+    │     ╰─ web_profiler.yaml
+    ├─ src
+    │  ├─ Command
+    │  ├─ Controller
+    │  │  ╰─ DefaultController.php
+    │  ╰─ Kernel.php
+    ╰─ templates
+       ╰─ base.html.twig
 
 Making a Custom Tree Style
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -285,3 +291,5 @@ The above code will output the following tree:
     🔵 🟢 🟠 🟡 Kernel.php
     🔵 🟠 🟡 templates
     🔵 🔴 🟠 🟡 base.html.twig
+
+.. _`details`: https://github.com/symfony/symfony/blob/7.3/src/Symfony/Component/Console/Helper/TreeStyle.php

From 4191969aff9f5737264eb238e9403199af9f3278 Mon Sep 17 00:00:00 2001
From: Pierre Ambroise <pierre27.ambroise@gmail.com>
Date: Mon, 24 Mar 2025 21:17:09 +0100
Subject: [PATCH 597/747] Document log_channel

---
 reference/configuration/framework.rst | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 528543a5178..7986140e050 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -1025,7 +1025,7 @@ exceptions
 
 **type**: ``array``
 
-Defines the :ref:`log level </logging>` and HTTP status code applied to the
+Defines the :ref:`log level </logging>`, :ref:`log channel </logging/channels_handlers>` and HTTP status code applied to the
 exceptions that match the given exception class:
 
 .. configuration-block::
@@ -1038,6 +1038,7 @@ exceptions that match the given exception class:
                 Symfony\Component\HttpKernel\Exception\BadRequestHttpException:
                     log_level: 'debug'
                     status_code: 422
+                    log_channel: 'custom_channel'
 
     .. code-block:: xml
 
@@ -1055,6 +1056,7 @@ exceptions that match the given exception class:
                     class="Symfony\Component\HttpKernel\Exception\BadRequestHttpException"
                     log-level="debug"
                     status-code="422"
+                    log-channel="custom_channel"
                 />
                 <!-- ... -->
             </framework:config>
@@ -1070,9 +1072,14 @@ exceptions that match the given exception class:
             $framework->exception(BadRequestHttpException::class)
                 ->logLevel('debug')
                 ->statusCode(422)
+                ->logChannel('custom_channel')
             ;
         };
 
+.. versionadded:: 7.3
+
+    The ``log_channel`` option was introduced in Symfony 7.3.
+
 The order in which you configure exceptions is important because Symfony will
 use the configuration of the first exception that matches ``instanceof``:
 

From 6d7c87f8eaea42c26004206fd1dc465df44e29cd Mon Sep 17 00:00:00 2001
From: Oviglo <ovigne.loic@gmail.com>
Date: Mon, 24 Mar 2025 10:51:29 +0100
Subject: [PATCH 598/747] [Security] Add methods param doc for isCsrfTokenValid
 attribute

---
 security/csrf.rst | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/security/csrf.rst b/security/csrf.rst
index be8348597c7..fa15cee3db3 100644
--- a/security/csrf.rst
+++ b/security/csrf.rst
@@ -288,6 +288,15 @@ object evaluated to the id::
         // ... do something, like deleting an object
     }
 
+You can use the ``methods`` parameter to the attribute to specify the HTTP methods that are allowed for
+the token validation, :class:`Symfony\\Component\\Security\\Http\\Attribute\\IsCsrfTokenValid` is ignored for other methods. By default, the attribute allows all methods::
+
+    #[IsCsrfTokenValid('delete-item', tokenKey: 'token', methods: ['DELETE'])]
+    public function delete(Post $post): Response
+    {
+        // ... delete the object
+    }
+
 .. versionadded:: 7.1
 
     The :class:`Symfony\\Component\\Security\\Http\\Attribute\\IsCsrfTokenValid`

From 84634a2c44d66ea4931e3ab991252a8e03a3000d Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 26 Mar 2025 10:31:19 +0100
Subject: [PATCH 599/747] Reword

---
 security/csrf.rst | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/security/csrf.rst b/security/csrf.rst
index fa15cee3db3..cc9b15253bc 100644
--- a/security/csrf.rst
+++ b/security/csrf.rst
@@ -288,8 +288,10 @@ object evaluated to the id::
         // ... do something, like deleting an object
     }
 
-You can use the ``methods`` parameter to the attribute to specify the HTTP methods that are allowed for
-the token validation, :class:`Symfony\\Component\\Security\\Http\\Attribute\\IsCsrfTokenValid` is ignored for other methods. By default, the attribute allows all methods::
+By default, the ``IsCsrfTokenValid`` attribute performs the CSRF token check for
+all HTTP methods. You can restrict this validation to specific methods using the
+``methods`` parameter. If the request uses a method not listed in the ``methods``
+array, the attribute is ignored for that request, and no CSRF validation occurs::
 
     #[IsCsrfTokenValid('delete-item', tokenKey: 'token', methods: ['DELETE'])]
     public function delete(Post $post): Response
@@ -302,6 +304,10 @@ the token validation, :class:`Symfony\\Component\\Security\\Http\\Attribute\\IsC
     The :class:`Symfony\\Component\\Security\\Http\\Attribute\\IsCsrfTokenValid`
     attribute was introduced in Symfony 7.1.
 
+.. versionadded:: 7.3
+
+    The ``methods`` parameter was introduced in Symfony 7.3.
+
 CSRF Tokens and Compression Side-Channel Attacks
 ------------------------------------------------
 

From 89e37c14121ed155d84a295554343f1ff1674057 Mon Sep 17 00:00:00 2001
From: MrYamous <matt.lempereur@gmail.com>
Date: Fri, 28 Mar 2025 08:28:17 +0100
Subject: [PATCH 600/747] messenger: allow to close connection

---
 messenger.rst | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index 0f1eba49a9f..06ad586407d 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2254,6 +2254,20 @@ on a case-by-case basis via the :class:`Symfony\\Component\\Messenger\\Stamp\\Se
     provides that control. See `SymfonyCasts' message serializer tutorial`_ for
     details.
 
+Closing connection
+~~~~~~~~~~~~~~~~~~
+
+When using a transport that requires a connection, you can close it using
+the :method:`Symfony\\Component\\Messenger\\Transport\\CloseableTransportInterface::close`
+method to allow free resources for long-running processes.
+
+This interface is implemented by the following transports: AmazonSqs, Amqp and Redis.
+If you want to close a Doctrine connection, this can be achieved :ref:`using middleware <middleware-for-doctrine>`.
+
+.. versionadded:: 7.3
+
+    The ``CloseableTransportInterface`` and ``close`` method were introduced in Symfony 7.3.
+
 Running Commands And External Processes
 ---------------------------------------
 

From 76f7e6e9506ebc8f04d956af63d9c4b723eca446 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 28 Mar 2025 16:59:53 +0100
Subject: [PATCH 601/747] Minor tweak

---
 reference/configuration/framework.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 7986140e050..3f34f792630 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -1025,8 +1025,8 @@ exceptions
 
 **type**: ``array``
 
-Defines the :ref:`log level </logging>`, :ref:`log channel </logging/channels_handlers>` and HTTP status code applied to the
-exceptions that match the given exception class:
+Defines the :ref:`log level </logging>`, :ref:`log channel </logging/channels_handlers>`
+and HTTP status code applied to the exceptions that match the given exception class:
 
 .. configuration-block::
 

From 1d02e0ca8e4be30395bcd45b183b3b1129de4cd6 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 31 Mar 2025 08:02:46 +0200
Subject: [PATCH 602/747] Minor tweaks

---
 messenger.rst | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index 06ad586407d..fc8f9491022 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2254,19 +2254,21 @@ on a case-by-case basis via the :class:`Symfony\\Component\\Messenger\\Stamp\\Se
     provides that control. See `SymfonyCasts' message serializer tutorial`_ for
     details.
 
-Closing connection
-~~~~~~~~~~~~~~~~~~
+Closing Connections
+~~~~~~~~~~~~~~~~~~~
 
-When using a transport that requires a connection, you can close it using
-the :method:`Symfony\\Component\\Messenger\\Transport\\CloseableTransportInterface::close`
-method to allow free resources for long-running processes.
+When using a transport that requires a connection, you can close it by calling the
+:method:`Symfony\\Component\\Messenger\\Transport\\CloseableTransportInterface::close`
+method to free up resources in long-running processes.
 
-This interface is implemented by the following transports: AmazonSqs, Amqp and Redis.
-If you want to close a Doctrine connection, this can be achieved :ref:`using middleware <middleware-for-doctrine>`.
+This interface is implemented by the following transports: AmazonSqs, Amqp, and Redis.
+If you need to close a Doctrine connection, you can do so
+:ref:`using middleware <middleware-for-doctrine>`.
 
 .. versionadded:: 7.3
 
-    The ``CloseableTransportInterface`` and ``close`` method were introduced in Symfony 7.3.
+    The ``CloseableTransportInterface`` and its ``close()`` method were introduced
+    in Symfony 7.3.
 
 Running Commands And External Processes
 ---------------------------------------

From bffad6daf493a377863a6389799623defd92de52 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 1 Apr 2025 09:05:00 +0200
Subject: [PATCH 603/747] Minor tweaks

---
 serializer.rst | 61 +++++++++++++++++++++++++-------------------------
 1 file changed, 30 insertions(+), 31 deletions(-)

diff --git a/serializer.rst b/serializer.rst
index 5f9144abae0..1fca42a3572 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -1544,13 +1544,13 @@ Named Serializers
 
     Named serializers were introduced in Symfony 7.2.
 
-Sometimes, you may need multiple configurations for the serializer, such
-as different default contexts, name converters, or sets of normalizers and
-encoders, depending on the use case. For example, when your application
-communicates with multiple APIs, each with its own set of rules.
+Sometimes, you may need multiple configurations for the serializer, such as
+different default contexts, name converters, or sets of normalizers and encoders,
+depending on the use case. For example, when your application communicates with
+multiple APIs, each of which follows its own set of serialization rules.
 
-This can be achieved by configuring multiple instances of the serializer
-using the ``named_serializers`` option:
+You can achieve this by configuring multiple serializer instances using
+the ``named_serializers`` option:
 
 .. configuration-block::
 
@@ -1633,7 +1633,7 @@ using :ref:`named aliases <autowiring-multiple-implementations-same-type>`::
     class PersonController extends AbstractController
     {
         public function index(
-            SerializerInterface $serializer,           // Default serializer
+            SerializerInterface $serializer,           // default serializer
             SerializerInterface $apiClient1Serializer, // api_client1 serializer
             #[Target('apiClient2.serializer')]         // api_client2 serializer
             SerializerInterface $customName,
@@ -1642,10 +1642,10 @@ using :ref:`named aliases <autowiring-multiple-implementations-same-type>`::
         }
     }
 
-Named serializers are configured with the default set of normalizers and encoders.
-
-You can register additional normalizers and encoders with a specific named
-serializer by adding a ``serializer`` attribute to
+By default, named serializers use the built-in set of normalizers and encoders,
+just like the main serializer service. However, you can customize them by
+registering additional normalizers or encoders for a specific named serializer.
+To do that, add a ``serializer`` attribute to
 the :ref:`serializer.normalizer <reference-dic-tags-serializer-normalizer>`
 or :ref:`serializer.encoder <reference-dic-tags-serializer-encoder>` tags:
 
@@ -1658,14 +1658,14 @@ or :ref:`serializer.encoder <reference-dic-tags-serializer-encoder>` tags:
             # ...
 
             Symfony\Component\Serializer\Normalizer\CustomNormalizer:
-                # Prevent this normalizer from automatically being included in the default serializer
+                # prevent this normalizer from being automatically added to the default serializer
                 autoconfigure: false
                 tags:
-                    # Include this normalizer in a single serializer
+                    # add this normalizer only to a specific named serializer
                     - serializer.normalizer: { serializer: 'api_client1' }
-                    # Include this normalizer in multiple serializers
+                    # add this normalizer to several named serializers
                     - serializer.normalizer: { serializer: [ 'api_client1', 'api_client2' ] }
-                    # Include this normalizer in all serializers (including the default one)
+                    # add this normalizer to all serializers, including the default one
                     - serializer.normalizer: { serializer: '*' }
 
     .. code-block:: xml
@@ -1680,20 +1680,19 @@ or :ref:`serializer.encoder <reference-dic-tags-serializer-encoder>` tags:
             <services>
                 <!-- ... -->
 
-                <!-- Disable autoconfigure to prevent this normalizer from automatically -->
-                <!-- being included in the default serializer -->
+                <!-- prevent this normalizer from being automatically added to the default serializer -->
                 <service
                     id="Symfony\Component\Serializer\Normalizer\CustomNormalizer"
                     autoconfigure="false"
                 >
-                    <!-- Include this normalizer in a single serializer -->
+                    <!-- add this normalizer only to a specific named serializer -->
                     <tag name="serializer.normalizer" serializer="api_client1"/>
 
-                    <!-- Include this normalizer in multiple serializers -->
+                    <!-- add this normalizer to several named serializers -->
                     <tag name="serializer.normalizer" serializer="api_client1"/>
                     <tag name="serializer.normalizer" serializer="api_client2"/>
 
-                    <!-- Include this normalizer in all serializers (including the default one) -->
+                    <!-- add this normalizer to all serializers, including the default one -->
                     <tag name="serializer.normalizer" serializer="*"/>
                 </service>
             </services>
@@ -1710,32 +1709,32 @@ or :ref:`serializer.encoder <reference-dic-tags-serializer-encoder>` tags:
             // ...
 
             $services->set(CustomNormalizer::class)
-                // Prevent this normalizer from automatically being included in the default serializer
+                // prevent this normalizer from being automatically added to the default serializer
                 ->autoconfigure(false)
 
-                // Include this normalizer in a single serializer
+                // add this normalizer only to a specific named serializer
                 ->tag('serializer.normalizer', ['serializer' => 'api_client1'])
-                // Include this normalizer in multiple serializers
+                // add this normalizer to several named serializers
                 ->tag('serializer.normalizer', ['serializer' => ['api_client1', 'api_client2']])
-                // Include this normalizer in all serializers (including the default one)
+                // add this normalizer to all serializers, including the default one
                 ->tag('serializer.normalizer', ['serializer' => '*'])
             ;
         };
 
-When the ``serializer`` attribute is not set, the service is registered with
+When the ``serializer`` attribute is not set, the service is registered only with
 the default serializer.
 
-Each normalizer and encoder used in a named serializer is tagged with
-a ``serializer.normalizer.<name>`` or ``serializer.encoder.<name>`` tag,
-which can be used to list their priorities using the following command:
+Each normalizer or encoder used in a named serializer is tagged with a
+``serializer.normalizer.<name>`` or ``serializer.encoder.<name>`` tag.
+You can inspect their priorities using the following command:
 
 .. code-block:: terminal
 
     $ php bin/console debug:container --tag serializer.<normalizer|encoder>.<name>
 
-Additionally, you can exclude the default set of normalizers and encoders by
-setting the ``include_built_in_normalizers`` and ``include_built_in_encoders``
-options to ``false``:
+Additionally, you can exclude the default set of normalizers and encoders from a
+named serializer by setting the ``include_built_in_normalizers`` and
+``include_built_in_encoders`` options to ``false``:
 
 .. configuration-block::
 

From 671eba4dc083e285978a5fb723f2bad4b93976e6 Mon Sep 17 00:00:00 2001
From: MrYamous <matt.lempereur@gmail.com>
Date: Wed, 2 Apr 2025 05:45:39 +0200
Subject: [PATCH 604/747] [FrameworkBundle] Deprecate setting the
 collect_serializer_data to false

---
 reference/configuration/framework.rst | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 3f34f792630..bcf99d989c7 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -2352,12 +2352,16 @@ Combine it with the ``collect`` option to enable/disable the profiler on demand:
 collect_serializer_data
 .......................
 
-**type**: ``boolean`` **default**: ``false``
+**type**: ``boolean`` **default**: ``true``
 
-Set this option to ``true`` to enable the serializer data collector and its
-profiler panel. When this option is ``true``, all normalizers and encoders are
+When this option is ``true``, all normalizers and encoders are
 decorated by traceable implementations that collect profiling information about them.
 
+.. deprecated:: 7.3
+
+    Setting the ``collect_serializer_data`` option to ``false`` is deprecated
+    since Symfony 7.3.
+
 .. _profiler-dsn:
 
 dsn

From 7b9ffb28b276674ae330e113c07e578b87055200 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 2 Apr 2025 17:00:44 +0200
Subject: [PATCH 605/747] Tweaks

---
 service_container/tags.rst | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/service_container/tags.rst b/service_container/tags.rst
index ae10f8ef51a..fab25ea910a 100644
--- a/service_container/tags.rst
+++ b/service_container/tags.rst
@@ -155,24 +155,8 @@ In a Symfony application, call this method in your kernel class::
         }
     }
 
-In a Symfony bundle, call this method in the ``load()`` method of the
-:doc:`bundle extension class </bundles/extension>`::
-
-    // src/DependencyInjection/MyBundleExtension.php
-    class MyBundleExtension extends Extension
-    {
-        // ...
-
-        public function load(array $configs, ContainerBuilder $container): void
-        {
-            $container->registerForAutoconfiguration(CustomInterface::class)
-                ->addTag('app.custom_tag')
-            ;
-        }
-    }
-
-or if you are following the recommended way for new bundles and for bundles following the
-:ref:`recommended directory structure <bundles-directory-structure>`::
+In bundles extending the :class:`Symfony\\Component\\HttpKernel\\Bundle\\AbstractBundle`
+class, call this method in the ``loadExtension()`` method of the main bundle class::
 
     // ...
     use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -190,6 +174,11 @@ or if you are following the recommended way for new bundles and for bundles foll
         }
     }
 
+.. note::
+
+    For bundles not extending the ``AbstractBundle`` class, call this method in
+    the ``load()`` method of the :doc:`bundle extension class </bundles/extension>`.
+
 Autoconfiguration registering is not limited to interfaces. It is possible
 to use PHP attributes to autoconfigure services by using the
 :method:`Symfony\\Component\\DependencyInjection\\ContainerBuilder::registerAttributeForAutoconfiguration`

From 6cfc92a41d05b0034ab643ab86538cd65b353670 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 3 Apr 2025 08:57:25 +0200
Subject: [PATCH 606/747] Minor tweaks

---
 messenger.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index c0822f97fdd..cefa6b8c0d4 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1865,9 +1865,9 @@ under the transport in ``messenger.yaml``:
     The Redis consumer group name
 
 ``consumer`` (default: ``consumer``)
-    Consumer name used in Redis. Allows to set explicit consumer name identifier.
-    Recommended for environments with multiple workers to prevent duplicate message processing.
-    Typically set via environment variable:
+    Consumer name used in Redis. Allows setting an explicit consumer name identifier.
+    Recommended in environments with multiple workers to prevent duplicate message
+    processing. Typically set via an environment variable:
 
     .. code-block:: yaml
 

From eb5f908bc97bd2b40d9bbe644d8c61674d1a7714 Mon Sep 17 00:00:00 2001
From: Kevin Bond <kevinbond@gmail.com>
Date: Fri, 4 Apr 2025 10:44:13 -0400
Subject: [PATCH 607/747] [RateLimiter] default `lock_factory` to `auto`

---
 rate_limiter.rst | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/rate_limiter.rst b/rate_limiter.rst
index 6c158ee52d0..1cef90828f5 100644
--- a/rate_limiter.rst
+++ b/rate_limiter.rst
@@ -461,9 +461,10 @@ simultaneous requests (e.g. three servers of a company hitting your API at the
 same time). Rate limiters use :doc:`locks </lock>` to protect their operations
 against these race conditions.
 
-By default, Symfony uses the global lock configured by ``framework.lock``, but
-you can use a specific :ref:`named lock <lock-named-locks>` via the
-``lock_factory`` option (or none at all):
+By default, if the :doc:`lock </lock>` component is installed, Symfony uses the
+global lock configured by ``framework.lock``, but you can use a specific
+:ref:`named lock <lock-named-locks>` via the ``lock_factory`` option (or none
+at all):
 
 .. configuration-block::
 

From 19b99dbe1b32290052fd6d211e75836efa00f20b Mon Sep 17 00:00:00 2001
From: Alexandre Daubois <alex.daubois@gmail.com>
Date: Fri, 4 Apr 2025 17:04:03 +0200
Subject: [PATCH 608/747] [Config] Add `NodeDefinition::docUrl()`

---
 components/config/definition.rst | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/components/config/definition.rst b/components/config/definition.rst
index 44189d9dd6f..4848af33ffe 100644
--- a/components/config/definition.rst
+++ b/components/config/definition.rst
@@ -546,6 +546,30 @@ and in XML:
     <!-- entries-per-page: This value is only used for the search results page. -->
     <config entries-per-page="25"/>
 
+You can also provide a URL to a full documentation page::
+
+    $rootNode
+        ->docUrl('Full documentation is available at https://example.com/docs/{version:major}.{version:minor}/reference.html')
+        ->children()
+            ->integerNode('entries_per_page')
+                ->defaultValue(25)
+            ->end()
+        ->end()
+    ;
+
+A few placeholders are available to customize the URL:
+
+* ``{version:major}``: The major version of the package currently installed
+* ``{version:minor}``: The minor version of the package currently installed
+* ``{package}``: The name of the package
+
+The placeholders will be replaced when printing the configuration tree with the
+``config:dump-reference`` command.
+
+.. versionadded:: 7.3
+
+    The ``docUrl()`` method was introduced in Symfony 7.3.
+
 Optional Sections
 -----------------
 

From 20ce1892efe75de46c9447a7a40baab5f6a5a2a0 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 7 Apr 2025 08:09:16 +0200
Subject: [PATCH 609/747] Added a versionadded directive

---
 rate_limiter.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/rate_limiter.rst b/rate_limiter.rst
index 1cef90828f5..81bd7f5689e 100644
--- a/rate_limiter.rst
+++ b/rate_limiter.rst
@@ -535,6 +535,12 @@ at all):
                 ;
         };
 
+.. versionadded:: 7.3
+
+    Before Symfony 7.3, configuring a rate limiter and using the default configured
+    lock factory (``lock.factory``) failed if the Symfony Lock component was not
+    installed in the application.
+
 .. _`DoS attacks`: https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html
 .. _`Apache mod_ratelimit`: https://httpd.apache.org/docs/current/mod/mod_ratelimit.html
 .. _`NGINX rate limiting`: https://www.nginx.com/blog/rate-limiting-nginx/

From b5efbcd9a777ac3e913a93fdfb96e1c0ef934fc7 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 7 Apr 2025 08:41:41 +0200
Subject: [PATCH 610/747] [Templates] Add a versionadded diretive for a command
 change

---
 templates.rst | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/templates.rst b/templates.rst
index a93bbe742c6..c6312abb33c 100644
--- a/templates.rst
+++ b/templates.rst
@@ -870,7 +870,6 @@ errors. It's useful to run it before deploying your application to production
     $ php bin/console lint:twig templates/article/recent_list.html.twig
 
     # you can also show the deprecated features used in your templates
-    # (only the first deprecation is shown, so run multiple times to catch all)
     $ php bin/console lint:twig --show-deprecations templates/email/
 
     # you can also excludes directories
@@ -880,6 +879,11 @@ errors. It's useful to run it before deploying your application to production
 
     The option to exclude directories was introduced in Symfony 7.1.
 
+.. versionadded:: 7.3
+
+    Before Symfony 7.3, the ``--show-deprecations`` option only displayed the
+    first deprecation found, so you had to run the command repeatedly.
+
 When running the linter inside `GitHub Actions`_, the output is automatically
 adapted to the format required by GitHub, but you can force that format too:
 

From 97de6eb32ef3f5d8d1b7d2c1fca5fffe04806c1f Mon Sep 17 00:00:00 2001
From: Antoine Makdessi <amakdessi@me.com>
Date: Mon, 7 Apr 2025 08:42:34 +0200
Subject: [PATCH 611/747] [Translator] document global variables feature
 configuration

---
 translation.rst | 61 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/translation.rst b/translation.rst
index c8996c08b48..7800161d77b 100644
--- a/translation.rst
+++ b/translation.rst
@@ -1160,6 +1160,67 @@ service argument with the :class:`Symfony\\Component\\Translation\\LocaleSwitche
 class to inject the locale switcher service. Otherwise, configure your services
 manually and inject the ``translation.locale_switcher`` service.
 
+.. _translation-global-variables:
+
+Global Variables
+~~~~~~~~~~~~~~~~
+
+The translator allows you to automatically configure global variables that will be available
+for the translation process. These global variables are defined in the ``translations.globals``
+option inside the main configuration file:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/translator.yaml
+        translator:
+            # ...
+            globals:
+                '%%app_name%%': 'My application'
+                '{app_version}': '1.2.3'
+                '{url}': { message: 'url', parameters: { scheme: 'https://' }, domain: 'global' }
+
+    .. code-block:: xml
+
+           <!-- config/packages/translation.xml -->
+           <?xml version="1.0" encoding="UTF-8" ?>
+           <container xmlns="http://symfony.com/schema/dic/services"
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+               xmlns:framework="http://symfony.com/schema/dic/symfony"
+               xsi:schemaLocation="http://symfony.com/schema/dic/services
+                   https://symfony.com/schema/dic/services/services-1.0.xsd
+                   http://symfony.com/schema/dic/symfony
+                   https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+               <framework:config>
+                   <framework:translator>
+                       <!-- ... -->
+                       <framework:global name="%%app_name%%">My application</framework:global>
+                       <framework:global name="{app_version}" value="1.2.3" />
+                       <framework:global name="{url}" message="url" domain="global">
+                            <framework:parameter name="scheme">https://</framework:parameter>
+                        </framework:global>
+                   </framework:translator>
+               </framework:config>
+           </container>
+
+    .. code-block:: php
+
+        // config/packages/translator.php
+        use Symfony\Config\TwigConfig;
+
+        return static function (TwigConfig $translator): void {
+            // ...
+            $translator->globals('%%app_name%%')->value('My application');
+            $translator->globals('{app_version}')->value('1.2.3');
+            $translator->globals('{url}')->value(['message' => 'url', 'parameters' => ['scheme' => 'https://']);
+        };
+
+.. versionadded:: 7.3
+
+    The ``translator:globals`` option was introduced in Symfony 7.3.
+
 .. _translation-debug:
 
 How to Find Missing or Unused Translation Messages

From 97d301a5c1c4a69f3958777b95d9c8ffcd4b928b Mon Sep 17 00:00:00 2001
From: Pierre Ambroise <pierre27.ambroise@gmail.com>
Date: Wed, 2 Apr 2025 11:41:05 +0200
Subject: [PATCH 612/747] [Messenger] Document stamps in HandleTrait::handle

---
 messenger.rst | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/messenger.rst b/messenger.rst
index fc8f9491022..159dd567a34 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2512,6 +2512,20 @@ wherever you need a query bus behavior instead of the ``MessageBusInterface``::
         }
     }
 
+You also can also add stamps when handling a message. For example, you can
+add an ``DoctrineFlushStamp`` to flush the entity manager after handling the message::
+
+    $this->handle(new SomeMessage($data), [new DoctrineFlushStamp()]);
+
+.. note::
+
+    If adding a stamp of the same type that already exists in the envelope,
+    both stamps will be kept (see `Envelopes & Stamps`_).
+
+.. versionadded:: 7.3
+
+    The ``$stamps`` parameter on the handle method was introduced in Symfony 7.3.
+
 Customizing Handlers
 --------------------
 

From c2c14fd74b50128ffd986919aec8c1fc7cf49cca Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 7 Apr 2025 09:40:08 +0200
Subject: [PATCH 613/747] Minor tweak

---
 messenger.rst | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index 47e0ad61906..b05056243c2 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2525,19 +2525,15 @@ wherever you need a query bus behavior instead of the ``MessageBusInterface``::
         }
     }
 
-You also can also add stamps when handling a message. For example, you can
-add an ``DoctrineFlushStamp`` to flush the entity manager after handling the message::
+You can also add new stamps when handling a message; they will be appended
+to the existing ones. For example, you can add a ``DoctrineFlushStamp`` to
+flush the entity manager after handling the message::
 
     $this->handle(new SomeMessage($data), [new DoctrineFlushStamp()]);
 
-.. note::
-
-    If adding a stamp of the same type that already exists in the envelope,
-    both stamps will be kept (see `Envelopes & Stamps`_).
-
 .. versionadded:: 7.3
 
-    The ``$stamps`` parameter on the handle method was introduced in Symfony 7.3.
+    The ``$stamps`` parameter of the ``handle()`` method was introduced in Symfony 7.3.
 
 Customizing Handlers
 --------------------

From 7f9f20fcd83889b0725ec7d6e7192af8dc2391c8 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 7 Apr 2025 10:16:39 +0200
Subject: [PATCH 614/747] [Mesenger] Fix code example

---
 messenger.rst | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/messenger.rst b/messenger.rst
index b05056243c2..9078a500d11 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2526,10 +2526,9 @@ wherever you need a query bus behavior instead of the ``MessageBusInterface``::
     }
 
 You can also add new stamps when handling a message; they will be appended
-to the existing ones. For example, you can add a ``DoctrineFlushStamp`` to
-flush the entity manager after handling the message::
+to the existing ones::
 
-    $this->handle(new SomeMessage($data), [new DoctrineFlushStamp()]);
+    $this->handle(new SomeMessage($data), [new SomeStamp(), new AnotherStamp()]);
 
 .. versionadded:: 7.3
 

From 11b256998374bdfbfa7a0155cf1274661a15811b Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 8 Apr 2025 11:03:16 +0200
Subject: [PATCH 615/747] Tweaks and rewords

---
 translation.rst | 139 +++++++++++++++++++++++++++---------------------
 1 file changed, 78 insertions(+), 61 deletions(-)

diff --git a/translation.rst b/translation.rst
index 7800161d77b..35751d7db5f 100644
--- a/translation.rst
+++ b/translation.rst
@@ -416,6 +416,84 @@ You can also specify the message domain and pass some additional variables:
     major difference: automatic output escaping is **not** applied to translations
     using a tag.
 
+Global Translation Parameters
+-----------------------------
+
+.. versionadded:: 7.3
+
+    The global translation parameters feature was introduced in Symfony 7.3.
+
+If the content of a translation parameter is repeated across multiple
+translation messages (e.g. a company name, or a version number), you can define
+it as a global translation parameter. This helps you avoid repeating the same
+values manually in each message.
+
+You can configure these global parameters in the ``translations.globals`` option
+of your main configuration file using either ``%...%`` or ``{...}`` syntax:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/translator.yaml
+        translator:
+            # ...
+            globals:
+                # when using the '%' wrapping characters, you must escape them
+                '%%app_name%%': 'My application'
+                '{app_version}': '1.2.3'
+                '{url}': { message: 'url', parameters: { scheme: 'https://' }, domain: 'global' }
+
+    .. code-block:: xml
+
+           <!-- config/packages/translation.xml -->
+           <?xml version="1.0" encoding="UTF-8" ?>
+           <container xmlns="http://symfony.com/schema/dic/services"
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+               xmlns:framework="http://symfony.com/schema/dic/symfony"
+               xsi:schemaLocation="http://symfony.com/schema/dic/services
+                   https://symfony.com/schema/dic/services/services-1.0.xsd
+                   http://symfony.com/schema/dic/symfony
+                   https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+               <framework:config>
+                   <framework:translator>
+                       <!-- ... -->
+                        <!-- when using the '%' wrapping characters, you must escape them -->
+                       <framework:global name="%%app_name%%">My application</framework:global>
+                       <framework:global name="{app_version}" value="1.2.3" />
+                       <framework:global name="{url}" message="url" domain="global">
+                            <framework:parameter name="scheme">https://</framework:parameter>
+                        </framework:global>
+                   </framework:translator>
+               </framework:config>
+           </container>
+
+    .. code-block:: php
+
+        // config/packages/translator.php
+        use Symfony\Config\TwigConfig;
+
+        return static function (TwigConfig $translator): void {
+            // ...
+            // when using the '%' wrapping characters, you must escape them
+            $translator->globals('%%app_name%%')->value('My application');
+            $translator->globals('{app_version}')->value('1.2.3');
+            $translator->globals('{url}')->value(['message' => 'url', 'parameters' => ['scheme' => 'https://']]);
+        };
+
+Once defined, you can use these parameters in translation messages anywhere in
+your application:
+
+.. code-block:: twig
+
+    {{ 'Application version: {version}'|trans }}
+    {# output: "Application version: 1.2.3" #}
+
+    {# parameters passed to the message override global parameters #}
+    {{ 'Package version: {version}'|trans({'{version}': '2.3.4'}) }}
+    # Displays "Package version: 2.3.4"
+
 Forcing the Translator Locale
 -----------------------------
 
@@ -1160,67 +1238,6 @@ service argument with the :class:`Symfony\\Component\\Translation\\LocaleSwitche
 class to inject the locale switcher service. Otherwise, configure your services
 manually and inject the ``translation.locale_switcher`` service.
 
-.. _translation-global-variables:
-
-Global Variables
-~~~~~~~~~~~~~~~~
-
-The translator allows you to automatically configure global variables that will be available
-for the translation process. These global variables are defined in the ``translations.globals``
-option inside the main configuration file:
-
-.. configuration-block::
-
-    .. code-block:: yaml
-
-        # config/packages/translator.yaml
-        translator:
-            # ...
-            globals:
-                '%%app_name%%': 'My application'
-                '{app_version}': '1.2.3'
-                '{url}': { message: 'url', parameters: { scheme: 'https://' }, domain: 'global' }
-
-    .. code-block:: xml
-
-           <!-- config/packages/translation.xml -->
-           <?xml version="1.0" encoding="UTF-8" ?>
-           <container xmlns="http://symfony.com/schema/dic/services"
-               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-               xmlns:framework="http://symfony.com/schema/dic/symfony"
-               xsi:schemaLocation="http://symfony.com/schema/dic/services
-                   https://symfony.com/schema/dic/services/services-1.0.xsd
-                   http://symfony.com/schema/dic/symfony
-                   https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
-
-               <framework:config>
-                   <framework:translator>
-                       <!-- ... -->
-                       <framework:global name="%%app_name%%">My application</framework:global>
-                       <framework:global name="{app_version}" value="1.2.3" />
-                       <framework:global name="{url}" message="url" domain="global">
-                            <framework:parameter name="scheme">https://</framework:parameter>
-                        </framework:global>
-                   </framework:translator>
-               </framework:config>
-           </container>
-
-    .. code-block:: php
-
-        // config/packages/translator.php
-        use Symfony\Config\TwigConfig;
-
-        return static function (TwigConfig $translator): void {
-            // ...
-            $translator->globals('%%app_name%%')->value('My application');
-            $translator->globals('{app_version}')->value('1.2.3');
-            $translator->globals('{url}')->value(['message' => 'url', 'parameters' => ['scheme' => 'https://']);
-        };
-
-.. versionadded:: 7.3
-
-    The ``translator:globals`` option was introduced in Symfony 7.3.
-
 .. _translation-debug:
 
 How to Find Missing or Unused Translation Messages

From fff52938f54f32cb6b246f73423affbe1365660b Mon Sep 17 00:00:00 2001
From: Kevin Bond <kevinbond@gmail.com>
Date: Tue, 8 Apr 2025 07:23:44 -0400
Subject: [PATCH 616/747] [RateLimiter] deprecate injecting
 `RateLimiterFactory`

---
 rate_limiter.rst | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/rate_limiter.rst b/rate_limiter.rst
index 81bd7f5689e..1036e80e682 100644
--- a/rate_limiter.rst
+++ b/rate_limiter.rst
@@ -230,6 +230,12 @@ prevents that number from being higher than 5,000).
 Rate Limiting in Action
 -----------------------
 
+.. versionadded:: 7.3
+
+    :class:`Symfony\\Component\\RateLimiter\\RateLimiterFactoryInterface` was
+    added and should now be used for autowiring instead of
+    :class:`Symfony\\Component\\RateLimiter\\RateLimiterFactory`.
+
 After having installed and configured the rate limiter, inject it in any service
 or controller and call the ``consume()`` method to try to consume a given number
 of tokens. For example, this controller uses the previous rate limiter to control
@@ -242,13 +248,13 @@ the number of requests to the API::
     use Symfony\Component\HttpFoundation\Request;
     use Symfony\Component\HttpFoundation\Response;
     use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
-    use Symfony\Component\RateLimiter\RateLimiterFactory;
+    use Symfony\Component\RateLimiter\RateLimiterFactoryInterface;
 
     class ApiController extends AbstractController
     {
         // if you're using service autowiring, the variable name must be:
         // "rate limiter name" (in camelCase) + "Limiter" suffix
-        public function index(Request $request, RateLimiterFactory $anonymousApiLimiter): Response
+        public function index(Request $request, RateLimiterFactoryInterface $anonymousApiLimiter): Response
         {
             // create a limiter based on a unique identifier of the client
             // (e.g. the client's IP address, a username/email, an API key, etc.)
@@ -291,11 +297,11 @@ using the ``reserve()`` method::
     use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
     use Symfony\Component\HttpFoundation\Request;
     use Symfony\Component\HttpFoundation\Response;
-    use Symfony\Component\RateLimiter\RateLimiterFactory;
+    use Symfony\Component\RateLimiter\RateLimiterFactoryInterface;
 
     class ApiController extends AbstractController
     {
-        public function registerUser(Request $request, RateLimiterFactory $authenticatedApiLimiter): Response
+        public function registerUser(Request $request, RateLimiterFactoryInterface $authenticatedApiLimiter): Response
         {
             $apiKey = $request->headers->get('apikey');
             $limiter = $authenticatedApiLimiter->create($apiKey);
@@ -350,11 +356,11 @@ the :class:`Symfony\\Component\\RateLimiter\\Reservation` object returned by the
     use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
     use Symfony\Component\HttpFoundation\Request;
     use Symfony\Component\HttpFoundation\Response;
-    use Symfony\Component\RateLimiter\RateLimiterFactory;
+    use Symfony\Component\RateLimiter\RateLimiterFactoryInterface;
 
     class ApiController extends AbstractController
     {
-        public function index(Request $request, RateLimiterFactory $anonymousApiLimiter): Response
+        public function index(Request $request, RateLimiterFactoryInterface $anonymousApiLimiter): Response
         {
             $limiter = $anonymousApiLimiter->create($request->getClientIp());
             $limit = $limiter->consume();

From 35349c17b05de94e156ca0247b2f4d9f887aaa3a Mon Sep 17 00:00:00 2001
From: Kevin Bond <kevinbond@gmail.com>
Date: Tue, 8 Apr 2025 07:45:37 -0400
Subject: [PATCH 617/747] [RateLimiter] compound rate limiter

---
 rate_limiter.rst | 117 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 117 insertions(+)

diff --git a/rate_limiter.rst b/rate_limiter.rst
index 81bd7f5689e..906e787e7e1 100644
--- a/rate_limiter.rst
+++ b/rate_limiter.rst
@@ -541,6 +541,123 @@ at all):
     lock factory (``lock.factory``) failed if the Symfony Lock component was not
     installed in the application.
 
+Compound Rate Limiter
+---------------------
+
+.. versionadded:: 7.3
+
+    Configuring compound rate limiters was added in 7.3.
+
+You can configure multiple rate limiters to work together:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/rate_limiter.yaml
+        framework:
+            rate_limiter:
+                two_per_minute:
+                    policy: 'fixed_window'
+                    limit: 2
+                    interval: '1 minute'
+                five_per_hour:
+                    policy: 'fixed_window'
+                    limit: 5
+                    interval: '1 hour'
+                contact_form:
+                    policy: 'compound'
+                    limiters: [two_per_minute, five_per_hour]
+
+    .. code-block:: xml
+
+        <!-- config/packages/rate_limiter.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony
+                https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <framework:config>
+                <framework:rate-limiter>
+                    <framework:limiter name="two_per_minute"
+                        policy="fixed_window"
+                        limit="2"
+                        interval="1 minute"
+                    />
+
+                    <framework:limiter name="five_per_hour"
+                        policy="fixed_window"
+                        limit="5"
+                        interval="1 hour"
+                    />
+
+                    <framework:limiter name="contact_form"
+                        policy="compound"
+                    >
+                        <limiter>two_per_minute</limiter>
+                        <limiter>five_per_hour</limiter>
+                    </framework:limiter>
+                </framework:rate-limiter>
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/rate_limiter.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            $framework->rateLimiter()
+                ->limiter('two_per_minute')
+                    ->policy('fixed_window')
+                    ->limit(2)
+                    ->interval('1 minute')
+                ;
+
+            $framework->rateLimiter()
+                ->limiter('two_per_minute')
+                    ->policy('fixed_window')
+                    ->limit(5)
+                    ->interval('1 hour')
+                ;
+
+            $framework->rateLimiter()
+                ->limiter('contact_form')
+                    ->policy('compound')
+                    ->limiters(['two_per_minute', 'five_per_hour'])
+                ;
+        };
+
+Then, inject and use as normal::
+
+    // src/Controller/ContactController.php
+    namespace App\Controller;
+
+    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+    use Symfony\Component\HttpFoundation\Request;
+    use Symfony\Component\HttpFoundation\Response;
+    use Symfony\Component\RateLimiter\RateLimiterFactory;
+
+    class ContactController extends AbstractController
+    {
+        public function registerUser(Request $request, RateLimiterFactoryInterface $contactFormLimiter): Response
+        {
+            $limiter = $contactFormLimiter->create($request->getClientIp());
+
+            if (false === $limiter->consume(1)->isAccepted()) {
+                // either of the two limiters has been reached
+            }
+
+            // ...
+        }
+
+        // ...
+    }
+
 .. _`DoS attacks`: https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html
 .. _`Apache mod_ratelimit`: https://httpd.apache.org/docs/current/mod/mod_ratelimit.html
 .. _`NGINX rate limiting`: https://www.nginx.com/blog/rate-limiting-nginx/

From 70716ab76d3e4066668c81ad1be465e3dc1a772e Mon Sep 17 00:00:00 2001
From: Hubert Lenoir <Jean-Beru@users.noreply.github.com>
Date: Tue, 8 Apr 2025 17:57:53 +0200
Subject: [PATCH 618/747] Update service_container.rst to 7.3

---
 service_container.rst | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/service_container.rst b/service_container.rst
index 30b69b8aa14..9a024e5e320 100644
--- a/service_container.rst
+++ b/service_container.rst
@@ -162,10 +162,6 @@ each time you ask for it.
                 # this creates a service per class whose id is the fully-qualified class name
                 App\:
                     resource: '../src/'
-                    exclude:
-                        - '../src/DependencyInjection/'
-                        - '../src/Entity/'
-                        - '../src/Kernel.php'
 
                 # order is important in this file because service definitions
                 # always *replace* previous ones; add your own service configuration below
@@ -187,7 +183,7 @@ each time you ask for it.
 
                     <!-- makes classes in src/ available to be used as services -->
                     <!-- this creates a service per class whose id is the fully-qualified class name -->
-                    <prototype namespace="App\" resource="../src/" exclude="../src/{DependencyInjection,Entity,Kernel.php}"/>
+                    <prototype namespace="App\" resource="../src/"/>
 
                     <!-- order is important in this file because service definitions
                          always *replace* previous ones; add your own service configuration below -->
@@ -212,8 +208,7 @@ each time you ask for it.
 
                 // makes classes in src/ available to be used as services
                 // this creates a service per class whose id is the fully-qualified class name
-                $services->load('App\\', '../src/')
-                    ->exclude('../src/{DependencyInjection,Entity,Kernel.php}');
+                $services->load('App\\', '../src/');
 
                 // order is important in this file because service definitions
                 // always *replace* previous ones; add your own service configuration below
@@ -221,9 +216,7 @@ each time you ask for it.
 
     .. tip::
 
-        The value of the ``resource`` and ``exclude`` options can be any valid
-        `glob pattern`_. The value of the ``exclude`` option can also be an
-        array of glob patterns.
+        The value of the ``resource`` option can be any valid `glob pattern`_.
 
     Thanks to this configuration, you can automatically use any classes from the
     ``src/`` directory as a service, without needing to manually configure

From c0f12c7408489bb8031b77d2caea5e3ce547781f Mon Sep 17 00:00:00 2001
From: "hubert.lenoir" <hubert.lenoir@sensiolabs.com>
Date: Tue, 8 Apr 2025 20:36:41 +0200
Subject: [PATCH 619/747] [Translation] Fix Lint (DOCtor-RST)

---
 translation.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/translation.rst b/translation.rst
index 35751d7db5f..86282090801 100644
--- a/translation.rst
+++ b/translation.rst
@@ -461,7 +461,7 @@ of your main configuration file using either ``%...%`` or ``{...}`` syntax:
                        <!-- ... -->
                         <!-- when using the '%' wrapping characters, you must escape them -->
                        <framework:global name="%%app_name%%">My application</framework:global>
-                       <framework:global name="{app_version}" value="1.2.3" />
+                       <framework:global name="{app_version}" value="1.2.3"/>
                        <framework:global name="{url}" message="url" domain="global">
                             <framework:parameter name="scheme">https://</framework:parameter>
                         </framework:global>

From ac9e20cad5195c101d843bcb6cb391f0b9316011 Mon Sep 17 00:00:00 2001
From: Mokhtar Tlili <mokhtar.tlili@vicoland.com>
Date: Tue, 8 Apr 2025 21:05:43 +0200
Subject: [PATCH 620/747] Add docs for bridge twig validator #20836

---
 bridge/twig/validation.rst | 63 ++++++++++++++++++++++++++++++++++++++
 index.rst                  |  1 +
 twig_bridge.rst            |  9 ++++++
 3 files changed, 73 insertions(+)
 create mode 100644 bridge/twig/validation.rst
 create mode 100644 twig_bridge.rst

diff --git a/bridge/twig/validation.rst b/bridge/twig/validation.rst
new file mode 100644
index 00000000000..e7b887f5588
--- /dev/null
+++ b/bridge/twig/validation.rst
@@ -0,0 +1,63 @@
+Validating Twig Template Syntax
+===============================
+
+The Twig Bridge provides a custom `Twig` constraint that allows validating
+whether a given string contains valid Twig syntax.
+
+This is particularly useful when template content is user-generated or
+configurable, and you want to ensure it can be safely rendered by the Twig engine.
+
+Installation
+------------
+
+This constraint is part of the `symfony/twig-bridge` package. Make sure it's installed:
+
+.. code-block:: terminal
+
+    $ composer require symfony/twig-bridge
+
+Usage
+-----
+
+To use the `Twig` constraint, annotate the property that should contain a valid
+Twig template::
+
+    use Symfony\Bridge\Twig\Validator\Constraints\Twig;
+
+    class Template
+    {
+        #[Twig]
+        private string $templateCode;
+    }
+
+If the template contains a syntax error, a validation error will be thrown.
+
+Constraint Options
+------------------
+
+**message**
+Customize the default error message when the template is invalid::
+
+    // ...
+    class Template
+    {
+        #[Twig(message: 'Your template contains a syntax error.')]
+        private string $templateCode;
+    }
+
+**skipDeprecations**
+By default, this option is set to `true`, which means Twig deprecation warnings
+are ignored during validation.
+
+If you want validation to fail when deprecated features are used in the template,
+set this to `false`::
+
+    // ...
+    class Template
+    {
+        #[Twig(skipDeprecations: false)]
+        private string $templateCode;
+    }
+
+This can be helpful when enforcing stricter template rules or preparing for major
+Twig version upgrades.
diff --git a/index.rst b/index.rst
index c566e5f8671..2bd09c8c0dc 100644
--- a/index.rst
+++ b/index.rst
@@ -60,6 +60,7 @@ Topics
     web_link
     webhook
     workflow
+    twig_bridge
 
 Components
 ----------
diff --git a/twig_bridge.rst b/twig_bridge.rst
new file mode 100644
index 00000000000..bb7d84f7e9a
--- /dev/null
+++ b/twig_bridge.rst
@@ -0,0 +1,9 @@
+Twig Bridge
+===========
+
+This bridge integrates Symfony with the Twig templating engine.
+
+.. toctree::
+   :maxdepth: 1
+
+   bridge/twig/validation

From a7a6c1d23db3430752cbdf59354aad47aaa4ef32 Mon Sep 17 00:00:00 2001
From: Kevin Bond <kevinbond@gmail.com>
Date: Tue, 8 Apr 2025 07:13:46 -0400
Subject: [PATCH 621/747] [Scheduler][Webhook] add screencast links

---
 scheduler.rst | 6 ++++++
 webhook.rst   | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/scheduler.rst b/scheduler.rst
index a09fabfc4ca..1630fd8dada 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -1,6 +1,11 @@
 Scheduler
 =========
 
+.. admonition:: Screencast
+    :class: screencast
+
+    Like video tutorials? Check out this `Scheduler quick-start screencast`_.
+
 The scheduler component manages task scheduling within your PHP application, like
 running a task each night at 3 AM, every two weeks except for holidays or any
 other custom schedule you might need.
@@ -1008,3 +1013,4 @@ helping you identify those messages when needed.
 .. _`cron command-line utility`: https://en.wikipedia.org/wiki/Cron
 .. _`crontab.guru website`: https://crontab.guru/
 .. _`relative formats`: https://www.php.net/manual/en/datetime.formats.php#datetime.formats.relative
+.. _`Scheduler quick-start screencast`: https://symfonycasts.com/screencast/mailtrap/bonus-symfony-scheduler
diff --git a/webhook.rst b/webhook.rst
index aba95cffb04..9d6b56c7ef0 100644
--- a/webhook.rst
+++ b/webhook.rst
@@ -15,6 +15,11 @@ Installation
 Usage in Combination with the Mailer Component
 ----------------------------------------------
 
+.. admonition:: Screencast
+    :class: screencast
+
+    Like video tutorials? Check out the `Webhook Component for Email Events screencast`_.
+
 When using a third-party mailer provider, you can use the Webhook component to
 receive webhook calls from this provider.
 
@@ -207,3 +212,4 @@ Creating a Custom Webhook
     Webhook.
 
 .. _`MakerBundle`: https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html
+.. _`Webhook Component for Email Events screencast`: https://symfonycasts.com/screencast/mailtrap/email-event-webhook

From 59fd3a3f167c8c799fad3256ace24dc8a72501de Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 9 Apr 2025 12:31:13 +0200
Subject: [PATCH 622/747] Tweaks

---
 service_container.rst        | 44 ++++++++++++++++++++++++++++++++++++
 service_container/import.rst |  7 ++----
 2 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/service_container.rst b/service_container.rst
index 9a024e5e320..6ae601cf724 100644
--- a/service_container.rst
+++ b/service_container.rst
@@ -223,6 +223,50 @@ each time you ask for it.
     it. Later, you'll learn how to :ref:`import many services at once
     <service-psr4-loader>` with resource.
 
+    If some files or directories in your project should not become services, you
+    can exclude them using the ``exclude`` option:
+
+        .. configuration-block::
+
+        .. code-block:: yaml
+
+            # config/services.yaml
+            services:
+                # ...
+                App\:
+                    resource: '../src/'
+                    exclude:
+                        - '../src/SomeDirectory/'
+                        - '../src/AnotherDirectory/'
+                        - '../src/SomeFile.php'
+
+        .. code-block:: xml
+
+            <!-- config/services.xml -->
+            <?xml version="1.0" encoding="UTF-8" ?>
+            <container xmlns="http://symfony.com/schema/dic/services"
+                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                xsi:schemaLocation="http://symfony.com/schema/dic/services
+                    https://symfony.com/schema/dic/services/services-1.0.xsd">
+
+                <services>
+                    <prototype namespace="App\" resource="../src/" exclude="../src/{SomeDirectory,AnotherDirectory,Kernel.php}"/>
+                    <!-- ... -->
+                </services>
+            </container>
+
+        .. code-block:: php
+
+            // config/services.php
+            namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+            return function(ContainerConfigurator $container): void {
+                // ...
+
+                $services->load('App\\', '../src/')
+                    ->exclude('../src/{SomeDirectory,AnotherDirectory,Kernel.php}');
+            };
+
     If you'd prefer to manually wire your service, you can
     :ref:`use explicit configuration <services-explicitly-configure-wire-services>`.
 
diff --git a/service_container/import.rst b/service_container/import.rst
index d5056032115..293cb5b97c2 100644
--- a/service_container/import.rst
+++ b/service_container/import.rst
@@ -82,7 +82,6 @@ a relative or absolute path to the imported file:
 
             App\:
                 resource: '../src/*'
-                exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
 
             # ...
 
@@ -104,8 +103,7 @@ a relative or absolute path to the imported file:
             <services>
                 <defaults autowire="true" autoconfigure="true"/>
 
-                <prototype namespace="App\" resource="../src/*"
-                    exclude="../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}"/>
+                <prototype namespace="App\" resource="../src/*"/>
 
                 <!-- ... -->
             </services>
@@ -127,8 +125,7 @@ a relative or absolute path to the imported file:
                     ->autoconfigure()
             ;
 
-            $services->load('App\\', '../src/*')
-                ->exclude('../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}');
+            $services->load('App\\', '../src/*');
         };
 
 When loading a configuration file, Symfony loads first the imported files and

From 518fc3a24cfd03eff976cf296997edc8e2aea2f8 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 9 Apr 2025 16:22:11 +0200
Subject: [PATCH 623/747] Minor tweak

---
 rate_limiter.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rate_limiter.rst b/rate_limiter.rst
index 4bd213d2363..3a517c37bd4 100644
--- a/rate_limiter.rst
+++ b/rate_limiter.rst
@@ -552,7 +552,7 @@ Compound Rate Limiter
 
 .. versionadded:: 7.3
 
-    Configuring compound rate limiters was added in 7.3.
+    Support for configuring compound rate limiters was introduced in Symfony 7.3.
 
 You can configure multiple rate limiters to work together:
 

From 344d8baac24247f9a0637bec61a2896e9404c43b Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 10 Apr 2025 09:12:48 +0200
Subject: [PATCH 624/747] Reorganized the contents of the new constraint

---
 bridge/twig/validation.rst        |  63 ---------------
 index.rst                         |   1 -
 reference/constraints/Twig.rst    | 130 ++++++++++++++++++++++++++++++
 reference/constraints/map.rst.inc |   1 +
 twig_bridge.rst                   |   9 ---
 5 files changed, 131 insertions(+), 73 deletions(-)
 delete mode 100644 bridge/twig/validation.rst
 create mode 100644 reference/constraints/Twig.rst
 delete mode 100644 twig_bridge.rst

diff --git a/bridge/twig/validation.rst b/bridge/twig/validation.rst
deleted file mode 100644
index e7b887f5588..00000000000
--- a/bridge/twig/validation.rst
+++ /dev/null
@@ -1,63 +0,0 @@
-Validating Twig Template Syntax
-===============================
-
-The Twig Bridge provides a custom `Twig` constraint that allows validating
-whether a given string contains valid Twig syntax.
-
-This is particularly useful when template content is user-generated or
-configurable, and you want to ensure it can be safely rendered by the Twig engine.
-
-Installation
-------------
-
-This constraint is part of the `symfony/twig-bridge` package. Make sure it's installed:
-
-.. code-block:: terminal
-
-    $ composer require symfony/twig-bridge
-
-Usage
------
-
-To use the `Twig` constraint, annotate the property that should contain a valid
-Twig template::
-
-    use Symfony\Bridge\Twig\Validator\Constraints\Twig;
-
-    class Template
-    {
-        #[Twig]
-        private string $templateCode;
-    }
-
-If the template contains a syntax error, a validation error will be thrown.
-
-Constraint Options
-------------------
-
-**message**
-Customize the default error message when the template is invalid::
-
-    // ...
-    class Template
-    {
-        #[Twig(message: 'Your template contains a syntax error.')]
-        private string $templateCode;
-    }
-
-**skipDeprecations**
-By default, this option is set to `true`, which means Twig deprecation warnings
-are ignored during validation.
-
-If you want validation to fail when deprecated features are used in the template,
-set this to `false`::
-
-    // ...
-    class Template
-    {
-        #[Twig(skipDeprecations: false)]
-        private string $templateCode;
-    }
-
-This can be helpful when enforcing stricter template rules or preparing for major
-Twig version upgrades.
diff --git a/index.rst b/index.rst
index 2bd09c8c0dc..c566e5f8671 100644
--- a/index.rst
+++ b/index.rst
@@ -60,7 +60,6 @@ Topics
     web_link
     webhook
     workflow
-    twig_bridge
 
 Components
 ----------
diff --git a/reference/constraints/Twig.rst b/reference/constraints/Twig.rst
new file mode 100644
index 00000000000..8435c191855
--- /dev/null
+++ b/reference/constraints/Twig.rst
@@ -0,0 +1,130 @@
+Twig Constraint
+===============
+
+.. versionadded:: 7.3
+
+    The ``Twig`` constraint was introduced in Symfony 7.3.
+
+Validates that a given string contains valid :ref:`Twig syntax <twig-language>`.
+This is particularly useful when template content is user-generated or
+configurable, and you want to ensure it can be rendered by the Twig engine.
+
+.. note::
+
+    Using this constraint requires having the ``symfony/twig-bridge`` package
+    installed in your application (e.g. by running ``composer require symfony/twig-bridge``).
+
+==========  ===================================================================
+Applies to  :ref:`property or method <validation-property-target>`
+Class       :class:`Symfony\\Bridge\\Twig\\Validator\\Constraints\\Twig`
+Validator   :class:`Symfony\\Bridge\\Twig\\Validator\\Constraints\\TwigValidator`
+==========  ===================================================================
+
+Basic Usage
+-----------
+
+Apply the ``Twig`` constraint to validate the contents of any property or the
+returned value of any method:
+
+    use Symfony\Bridge\Twig\Validator\Constraints\Twig;
+
+    class Template
+    {
+        #[Twig]
+        private string $templateCode;
+    }
+
+.. configuration-block::
+
+    .. code-block:: php-attributes
+
+        // src/Entity/Page.php
+        namespace App\Entity;
+
+        use Symfony\Bridge\Twig\Validator\Constraints\Twig;
+
+        class Page
+        {
+            #[Twig]
+            private string $templateCode;
+        }
+
+    .. code-block:: yaml
+
+        # config/validator/validation.yaml
+        App\Entity\Page:
+            properties:
+                templateCode:
+                    - Symfony\Bridge\Twig\Validator\Constraints\Twig: ~
+
+    .. code-block:: xml
+
+        <!-- config/validator/validation.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
+
+            <class name="App\Entity\Page">
+                <property name="templateCode">
+                    <constraint name="Symfony\Bridge\Twig\Validator\Constraints\Twig"/>
+                </property>
+            </class>
+        </constraint-mapping>
+
+    .. code-block:: php
+
+        // src/Entity/Page.php
+        namespace App\Entity;
+
+        use Symfony\Bridge\Twig\Validator\Constraints\Twig;
+        use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+        class Page
+        {
+            // ...
+
+            public static function loadValidatorMetadata(ClassMetadata $metadata): void
+            {
+                $metadata->addPropertyConstraint('templateCode', new Twig());
+            }
+        }
+
+Constraint Options
+------------------
+
+``message``
+~~~~~~~~~~~
+
+**type**: ``message`` **default**: ``This value is not a valid Twig template.``
+
+This is the message displayed when the given string does *not* contain valid Twig syntax::
+
+    // ...
+
+    class Page
+    {
+        #[Twig(message: 'Check this Twig code; it contains errors.')]
+        private string $templateCode;
+    }
+
+This message has no parameters.
+
+``skipDeprecations``
+~~~~~~~~~~~~~~~~~~~~
+
+**type**: ``boolean`` **default**: ``true``
+
+If ``true``, Twig deprecation warnings are ignored during validation. Set it to
+``false`` to trigger validation errors when the given Twig code contains any deprecations::
+
+    // ...
+
+    class Page
+    {
+        #[Twig(skipDeprecations: false)]
+        private string $templateCode;
+    }
+
+This can be helpful when enforcing stricter template rules or preparing for major
+Twig version upgrades.
diff --git a/reference/constraints/map.rst.inc b/reference/constraints/map.rst.inc
index 58801a8c653..c2396ae3af7 100644
--- a/reference/constraints/map.rst.inc
+++ b/reference/constraints/map.rst.inc
@@ -34,6 +34,7 @@ String Constraints
 * :doc:`PasswordStrength </reference/constraints/PasswordStrength>`
 * :doc:`Regex </reference/constraints/Regex>`
 * :doc:`Slug </reference/constraints/Slug>`
+* :doc:`Twig </reference/constraints/Twig>`
 * :doc:`Ulid </reference/constraints/Ulid>`
 * :doc:`Url </reference/constraints/Url>`
 * :doc:`UserPassword </reference/constraints/UserPassword>`
diff --git a/twig_bridge.rst b/twig_bridge.rst
deleted file mode 100644
index bb7d84f7e9a..00000000000
--- a/twig_bridge.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Twig Bridge
-===========
-
-This bridge integrates Symfony with the Twig templating engine.
-
-.. toctree::
-   :maxdepth: 1
-
-   bridge/twig/validation

From 5ca3039e8bf1344368e098a83ac47749aeff7748 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mat=C4=9Bj=20Hump=C3=A1l?= <finwe@users.noreply.github.com>
Date: Mon, 14 Apr 2025 12:04:35 +0200
Subject: [PATCH 625/747] Specify explicitly what a priority of message
 handlers mean

---
 messenger.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index 484a5cbdaff..f504a470336 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2468,7 +2468,7 @@ Possible options to configure with tags are:
     Name of the method that will process the message.
 
 ``priority``
-    Priority of the handler when multiple handlers can process the same message.
+    Priority of the handler when multiple handlers can process the same message; higher values will be processed first.
 
 .. _handler-subscriber-options:
 

From c4cf202b2614a726be6694161b6eec7aba253588 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@open.de>
Date: Thu, 17 Apr 2025 08:34:15 +0200
Subject: [PATCH 626/747] fix configuration block indentation

---
 service_container.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/service_container.rst b/service_container.rst
index 6ae601cf724..6086ae1d946 100644
--- a/service_container.rst
+++ b/service_container.rst
@@ -226,7 +226,7 @@ each time you ask for it.
     If some files or directories in your project should not become services, you
     can exclude them using the ``exclude`` option:
 
-        .. configuration-block::
+    .. configuration-block::
 
         .. code-block:: yaml
 

From fa8f5b191bf11cd1c8e29f56fea743855d597e54 Mon Sep 17 00:00:00 2001
From: Alexander Hofbauer <a.hofbauer@fify.at>
Date: Thu, 17 Apr 2025 09:15:22 +0200
Subject: [PATCH 627/747] [Mailer] Document email.image name parameter

---
 mailer.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/mailer.rst b/mailer.rst
index a6b5eb819d8..034f9bdfe97 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -1093,6 +1093,14 @@ the email contents:
     <h1>Welcome {{ email.toName }}!</h1>
     {# ... #}
 
+By default this will create an attachment using the file path as filename:
+``Content-Disposition: inline; name="cid..."; filename="@images/logo.png"``.
+This behavior can be overridden by passing a name (the third argument):
+
+.. code-block:: html+twig
+
+    <img src="{{ email.image('@images/logo.png', name: 'my-logo.png') }}" alt="My Logo">
+
 .. _mailer-inline-css:
 
 Inlining CSS Styles

From 316c8ac333d822e1b5d68aa8bdbc25f8923c453c Mon Sep 17 00:00:00 2001
From: Pierre Ambroise <pierre27.ambroise@gmail.com>
Date: Thu, 17 Apr 2025 16:39:24 +0200
Subject: [PATCH 628/747] Add when argument to AsAlias

---
 service_container/alias_private.rst | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/service_container/alias_private.rst b/service_container/alias_private.rst
index f99f7cb5f3e..84632c1d89b 100644
--- a/service_container/alias_private.rst
+++ b/service_container/alias_private.rst
@@ -181,6 +181,27 @@ This means that when using the container directly, you can access the
             # ...
             app.mailer: '@App\Mail\PhpMailer'
 
+The ``#[AsAlias]`` attribute also support per-environment configuration
+via the ``when`` argument::
+
+    // src/Mail/PhpMailer.php
+    namespace App\Mail;
+
+    // ...
+    use Symfony\Component\DependencyInjection\Attribute\AsAlias;
+
+    #[AsAlias(id: 'app.mailer', when: 'dev')]
+    class PhpMailer
+    {
+        // ...
+    }
+
+You can pass either a string or an array of strings to the ``when`` argument.
+
+.. versionadded:: 7.3
+
+    The ``when`` argument on the ``#[AsAlias]`` attribute was introduced in Symfony 7.3.
+
 .. tip::
 
     When using ``#[AsAlias]`` attribute, you may omit passing ``id`` argument

From 5482c8281ad9bf346362e06f7988e83dd4282c6a Mon Sep 17 00:00:00 2001
From: Kevin Bond <kevinbond@gmail.com>
Date: Thu, 17 Apr 2025 20:14:01 -0400
Subject: [PATCH 629/747] [Routing] add tip about using `symfony/clock` with
 `UriSigner`

---
 routing.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/routing.rst b/routing.rst
index a9ada1fc44b..0e1a46a505b 100644
--- a/routing.rst
+++ b/routing.rst
@@ -2815,6 +2815,16 @@ argument of :method:`Symfony\\Component\\HttpFoundation\\UriSigner::sign`::
     Starting with Symfony 7.3, signed URI hashes no longer include the ``/`` or
     ``+`` characters, as these may cause issues with certain clients.
 
+.. tip::
+
+    If ``symfony/clock`` is installed, it is used for creating and verifying the
+    expiration. This allows you to :ref:`mock the current time in your tests
+    <clock_writing-tests>`.
+
+.. versionadded:: 7.3
+
+    ``symfony/clock`` support was added to ``UriSigner`` in Symfony 7.3.
+
 Troubleshooting
 ---------------
 

From aa3b1674ea0202c0d3966ee82f04836fe33479ec Mon Sep 17 00:00:00 2001
From: Kevin Bond <kevinbond@gmail.com>
Date: Fri, 18 Apr 2025 19:34:27 -0400
Subject: [PATCH 630/747] [Routing] document `UriSigner::verify()`

---
 routing.rst | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/routing.rst b/routing.rst
index a9ada1fc44b..19c2ae1a5a6 100644
--- a/routing.rst
+++ b/routing.rst
@@ -2810,10 +2810,30 @@ argument of :method:`Symfony\\Component\\HttpFoundation\\UriSigner::sign`::
 
     The feature to add an expiration date for a signed URI was introduced in Symfony 7.1.
 
+If you need to know the reason why a signed URI is invalid, you can use the
+``verify()`` method which throws exceptions on failure::
+
+    use Symfony\Component\HttpFoundation\Exception\ExpiredSignedUriException;
+    use Symfony\Component\HttpFoundation\Exception\UnsignedUriException;
+    use Symfony\Component\HttpFoundation\Exception\UnverifiedSignedUriException;
+
+    // ...
+
+    try {
+        $uriSigner->verify($uri); // $uri can be a string or Request object
+
+        // the URI is valid
+    } catch (UnsignedUriException) {
+        // the URI isn't signed
+    } catch (UnverifiedSignedUriException) {
+        // the URI is signed but the signature is invalid
+    } catch (ExpiredSignedUriException) {
+        // the URI is signed but expired
+    }
+
 .. versionadded:: 7.3
 
-    Starting with Symfony 7.3, signed URI hashes no longer include the ``/`` or
-    ``+`` characters, as these may cause issues with certain clients.
+    The ``verify()`` method was introduced in Symfony 7.3.
 
 Troubleshooting
 ---------------

From e7613b0e2af243005b9fb66c9d696f74005a645a Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Sat, 19 Apr 2025 19:03:15 +0200
Subject: [PATCH 631/747] [Validator] Add filenameCharset and filenameCountUnit
 options to File constraint

---
 reference/constraints/File.rst | 54 ++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/reference/constraints/File.rst b/reference/constraints/File.rst
index 495c19f9cbe..62efa6cc08e 100644
--- a/reference/constraints/File.rst
+++ b/reference/constraints/File.rst
@@ -274,6 +274,31 @@ You can find a list of existing mime types on the `IANA website`_.
 If set, the validator will check that the filename of the underlying file
 doesn't exceed a certain length.
 
+``filenameCountUnit``
+~~~~~~~~~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``File::FILENAME_COUNT_BYTES``
+
+The character count unit to use for the filename max length check.
+By default :phpfunction:`strlen` is used, which counts the length of the string in bytes.
+
+Can be one of the following constants of the
+:class:`Symfony\\Component\\Validator\\Constraints\\File` class:
+
+* ``FILENAME_COUNT_BYTES``: Uses :phpfunction:`strlen` counting the length of the
+  string in bytes.
+* ``FILENAME_COUNT_CODEPOINTS``: Uses :phpfunction:`mb_strlen` counting the length
+  of the string in Unicode code points. Simple (multibyte) Unicode characters count
+  as 1 character, while for example ZWJ sequences of composed emojis count as
+  multiple characters.
+* ``FILENAME_COUNT_GRAPHEMES``: Uses :phpfunction:`grapheme_strlen` counting the
+  length of the string in graphemes, i.e. even emojis and ZWJ sequences of composed
+  emojis count as 1 character.
+
+.. versionadded:: 7.3
+
+    The ``filenameCountUnit`` option was introduced in Symfony 7.3.
+
 ``filenameTooLongMessage``
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -290,6 +315,35 @@ Parameter                       Description
 ``{{ filename_max_length }}``   Maximum number of characters allowed
 ==============================  ==============================================================
 
+``filenameCharset``
+~~~~~~~~~~~~~~~~~~~
+
+**type**: ``string``  **default**: ``null``
+
+The charset to be used when computing value's filename max length with the
+:phpfunction:`mb_check_encoding` and :phpfunction:`mb_strlen`
+PHP functions.
+
+``filenameCharsetMessage``
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**type**: ``string`` **default**: ``This filename does not match the expected charset.``
+
+The message that will be shown if the value is not using the given `filenameCharsetMessage`_.
+
+You can use the following parameters in this message:
+
+=================  ============================================================
+Parameter          Description
+=================  ============================================================
+``{{ charset }}``  The expected charset
+``{{ name }}``     The current (invalid) value
+=================  ============================================================
+
+.. versionadded:: 7.3
+
+    The ``filenameCharset`` and ``filenameCharsetMessage`` options were introduced in Symfony 7.3.
+
 ``extensionsMessage``
 ~~~~~~~~~~~~~~~~~~~~~
 

From 76c4720d47de37c43d0a87cc1c61fe8d1216605c Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 22 Apr 2025 17:17:11 +0200
Subject: [PATCH 632/747] Minor tweaks

---
 service_container/alias_private.rst | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/service_container/alias_private.rst b/service_container/alias_private.rst
index 84632c1d89b..22bf649d861 100644
--- a/service_container/alias_private.rst
+++ b/service_container/alias_private.rst
@@ -181,8 +181,8 @@ This means that when using the container directly, you can access the
             # ...
             app.mailer: '@App\Mail\PhpMailer'
 
-The ``#[AsAlias]`` attribute also support per-environment configuration
-via the ``when`` argument::
+The ``#[AsAlias]`` attribute can also be limited to one or more specific
+:ref:`config environments <configuration-environments>` using the ``when`` argument::
 
     // src/Mail/PhpMailer.php
     namespace App\Mail;
@@ -196,11 +196,16 @@ via the ``when`` argument::
         // ...
     }
 
-You can pass either a string or an array of strings to the ``when`` argument.
+    // pass an array to apply it in multiple config environments
+    #[AsAlias(id: 'app.mailer', when: ['dev', 'test'])]
+    class PhpMailer
+    {
+        // ...
+    }
 
 .. versionadded:: 7.3
 
-    The ``when`` argument on the ``#[AsAlias]`` attribute was introduced in Symfony 7.3.
+    The ``when`` argument of the ``#[AsAlias]`` attribute was introduced in Symfony 7.3.
 
 .. tip::
 

From 6350e2ea71430fa106bd7873a4c384153fab134e Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 22 Apr 2025 17:49:02 +0200
Subject: [PATCH 633/747] Minor tweaks

---
 routing.rst | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/routing.rst b/routing.rst
index 672f331291b..663e8518504 100644
--- a/routing.rst
+++ b/routing.rst
@@ -2837,13 +2837,14 @@ If you need to know the reason why a signed URI is invalid, you can use the
 
 .. tip::
 
-    If ``symfony/clock`` is installed, it is used for creating and verifying the
-    expiration. This allows you to :ref:`mock the current time in your tests
+    If ``symfony/clock`` is installed, it will be used to create and verify
+    expirations. This allows you to :ref:`mock the current time in your tests
     <clock_writing-tests>`.
 
 .. versionadded:: 7.3
 
-    ``symfony/clock`` support was added to ``UriSigner`` in Symfony 7.3.
+    Support for :doc:`Symfony Clock </components/clock>` in ``UriSigner`` was
+    introduced in Symfony 7.3.
 
 Troubleshooting
 ---------------

From 9f7cc9d5d899a2afc46ca1be67f2242a21326168 Mon Sep 17 00:00:00 2001
From: Arnaud Thibaudet <athib.pro@gmail.com>
Date: Thu, 24 Apr 2025 10:17:29 +0200
Subject: [PATCH 634/747] Fix typo on parameter name

Signed-off-by: Arnaud Thibaudet <athib.pro@gmail.com>
---
 translation.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/translation.rst b/translation.rst
index 86282090801..23949b7e67f 100644
--- a/translation.rst
+++ b/translation.rst
@@ -487,11 +487,11 @@ your application:
 
 .. code-block:: twig
 
-    {{ 'Application version: {version}'|trans }}
+    {{ 'Application version: {app_version}'|trans }}
     {# output: "Application version: 1.2.3" #}
 
     {# parameters passed to the message override global parameters #}
-    {{ 'Package version: {version}'|trans({'{version}': '2.3.4'}) }}
+    {{ 'Package version: {app_version}'|trans({'{app_version}': '2.3.4'}) }}
     # Displays "Package version: 2.3.4"
 
 Forcing the Translator Locale

From 7292c30bc9ac84a590cf7a63edb83a0a7419ab35 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 25 Apr 2025 10:30:00 +0200
Subject: [PATCH 635/747] Tweaks

---
 mailer.rst | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index 034f9bdfe97..d368048aec8 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -1093,13 +1093,17 @@ the email contents:
     <h1>Welcome {{ email.toName }}!</h1>
     {# ... #}
 
-By default this will create an attachment using the file path as filename:
+By default this will create an attachment using the file path as file name:
 ``Content-Disposition: inline; name="cid..."; filename="@images/logo.png"``.
-This behavior can be overridden by passing a name (the third argument):
+This behavior can be overridden by passing a custom file name as the third argument:
 
 .. code-block:: html+twig
 
-    <img src="{{ email.image('@images/logo.png', name: 'my-logo.png') }}" alt="My Logo">
+    <img src="{{ email.image('@images/logo.png', 'image/png', 'logo-acme.png') }}" alt="ACME Logo">
+
+.. versionadded:: 7.3
+
+    The third argument of ``email.image()`` was introduced in Symfony 7.3.
 
 .. _mailer-inline-css:
 

From b47463617dec7ad81e3d4ab6a4836a23f78764fc Mon Sep 17 00:00:00 2001
From: Kevin Bond <kevinbond@gmail.com>
Date: Fri, 25 Apr 2025 11:05:10 -0400
Subject: [PATCH 636/747] [Scheduler] add note about the recipe

---
 scheduler.rst | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/scheduler.rst b/scheduler.rst
index 1630fd8dada..2126801071c 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -27,10 +27,10 @@ install the scheduler component:
 
     $ composer require symfony/scheduler
 
-.. tip::
+.. note::
 
-    Starting in `MakerBundle`_ ``v1.58.0``, you can run ``php bin/console make:schedule``
-    to generate a basic schedule, that you can customize to create your own Scheduler.
+    The Symfony Scheduler Flex recipe creates an initial schedule that's ready
+    to start adding your tasks.
 
 Symfony Scheduler Basics
 ------------------------
@@ -1007,7 +1007,6 @@ When using the ``RedispatchMessage``, Symfony will attach a
 :class:`Symfony\\Component\\Scheduler\\Messenger\\ScheduledStamp` to the message,
 helping you identify those messages when needed.
 
-.. _`MakerBundle`: https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html
 .. _`Deploying to Production`: https://symfony.com/doc/current/messenger.html#deploying-to-production
 .. _`Memoizing`: https://en.wikipedia.org/wiki/Memoization
 .. _`cron command-line utility`: https://en.wikipedia.org/wiki/Cron

From 969ba97fc48192a21a1241508f2e19894f971a37 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 25 Apr 2025 17:40:43 +0200
Subject: [PATCH 637/747] [Validator] Fix minor syntax issue

---
 reference/constraints/Twig.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/constraints/Twig.rst b/reference/constraints/Twig.rst
index 8435c191855..e38b4507d7a 100644
--- a/reference/constraints/Twig.rst
+++ b/reference/constraints/Twig.rst
@@ -24,7 +24,7 @@ Basic Usage
 -----------
 
 Apply the ``Twig`` constraint to validate the contents of any property or the
-returned value of any method:
+returned value of any method::
 
     use Symfony\Bridge\Twig\Validator\Constraints\Twig;
 

From 49a3f18ecc10cff61a96d05037673966da867fe0 Mon Sep 17 00:00:00 2001
From: Aubert Jordan <jordan@les-tilleuls.coop>
Date: Mon, 28 Apr 2025 10:57:19 +0200
Subject: [PATCH 638/747] Update custom_normalizer.rst

Update `normalize` signature according to `NormalizerInterface`
---
 serializer/custom_normalizer.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/serializer/custom_normalizer.rst b/serializer/custom_normalizer.rst
index b357f3f91ad..eafabde50cb 100644
--- a/serializer/custom_normalizer.rst
+++ b/serializer/custom_normalizer.rst
@@ -36,9 +36,9 @@ normalization process::
         ) {
         }
 
-        public function normalize(mixed $object, ?string $format = null, array $context = []): array
+        public function normalize(mixed $data, ?string $format = null, array $context = []): array
         {
-            $data = $this->normalizer->normalize($object, $format, $context);
+            $data = $this->normalizer->normalize($data, $format, $context);
 
             // Here, add, edit, or delete some data:
             $data['href']['self'] = $this->router->generate('topic_show', [

From 40a99acbbeba9f4aa3b2f09821c52443446aa8a2 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Mon, 28 Apr 2025 12:10:49 +0200
Subject: [PATCH 639/747] Add PHP config support for routing

---
 configuration/micro_kernel_trait.rst | 10 ++++++++--
 controller/error_pages.rst           | 12 +++++++++---
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/configuration/micro_kernel_trait.rst b/configuration/micro_kernel_trait.rst
index f919b1f7a74..c372d876651 100644
--- a/configuration/micro_kernel_trait.rst
+++ b/configuration/micro_kernel_trait.rst
@@ -297,8 +297,8 @@ Now it looks like this::
         {
             // import the WebProfilerRoutes, only if the bundle is enabled
             if (isset($this->bundles['WebProfilerBundle'])) {
-                $routes->import('@WebProfilerBundle/Resources/config/routing/wdt.xml')->prefix('/_wdt');
-                $routes->import('@WebProfilerBundle/Resources/config/routing/profiler.xml')->prefix('/_profiler');
+                $routes->import('@WebProfilerBundle/Resources/config/routing/wdt.php', 'php')->prefix('/_wdt');
+                $routes->import('@WebProfilerBundle/Resources/config/routing/profiler.php', 'php')->prefix('/_profiler');
             }
 
             // load the routes defined as PHP attributes
@@ -310,6 +310,12 @@ Now it looks like this::
         // to override the default locations for these directories
     }
 
+
+.. versionadded:: 7.3
+
+    The ``wdt.php`` and ``profiler.php`` files were introduced in Symfony 7.3.
+    Previously, you had to import ``wdt.xml`` and ``profiler.xml``
+
 Before continuing, run this command to add support for the new dependencies:
 
 .. code-block:: terminal
diff --git a/controller/error_pages.rst b/controller/error_pages.rst
index 96856764ece..06087837437 100644
--- a/controller/error_pages.rst
+++ b/controller/error_pages.rst
@@ -154,7 +154,8 @@ automatically when installing ``symfony/framework-bundle``):
         # config/routes/framework.yaml
         when@dev:
             _errors:
-                resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
+                resource: '@FrameworkBundle/Resources/config/routing/errors.php'
+                type:     php
                 prefix:   /_error
 
     .. code-block:: xml
@@ -167,7 +168,7 @@ automatically when installing ``symfony/framework-bundle``):
                 https://symfony.com/schema/routing/routing-1.0.xsd">
 
             <when env="dev">
-                <import resource="@FrameworkBundle/Resources/config/routing/errors.xml" prefix="/_error"/>
+                <import resource="@FrameworkBundle/Resources/config/routing/errors.php" type="php" prefix="/_error"/>
             </when>
         </routes>
 
@@ -178,7 +179,7 @@ automatically when installing ``symfony/framework-bundle``):
 
         return function (RoutingConfigurator $routes): void {
             if ('dev' === $routes->env()) {
-                $routes->import('@FrameworkBundle/Resources/config/routing/errors.xml')
+                $routes->import('@FrameworkBundle/Resources/config/routing/errors.php', 'php')
                     ->prefix('/_error')
                 ;
             }
@@ -191,6 +192,11 @@ need to replace ``http://localhost/`` by the host used in your local setup):
 * ``http://localhost/_error/{statusCode}`` for HTML
 * ``http://localhost/_error/{statusCode}.{format}`` for any other format
 
+.. versionadded:: 7.3
+
+    The ``errors.php`` file was introduced in Symfony 7.3.
+    Previously, you had to import ``errors.xml``
+
 .. _overriding-non-html-error-output:
 
 Overriding Error output for non-HTML formats

From b430e186c1b226a3ac78dfd3caa056d7c0ebe6e7 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 29 Apr 2025 08:05:22 +0200
Subject: [PATCH 640/747] Minor tweaks

---
 scheduler.rst | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/scheduler.rst b/scheduler.rst
index 2126801071c..608717c9b8e 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -20,8 +20,7 @@ stack Symfony application.
 Installation
 ------------
 
-In applications using :ref:`Symfony Flex <symfony-flex>`, run this command to
-install the scheduler component:
+Run this command to install the scheduler component:
 
 .. code-block:: terminal
 
@@ -29,8 +28,8 @@ install the scheduler component:
 
 .. note::
 
-    The Symfony Scheduler Flex recipe creates an initial schedule that's ready
-    to start adding your tasks.
+    In applications using :ref:`Symfony Flex <symfony-flex>`, installing the component
+    also creates an initial schedule that's ready to start adding your tasks.
 
 Symfony Scheduler Basics
 ------------------------

From 15849ea5cead4abf20e5dd4d7d14a4cff366d291 Mon Sep 17 00:00:00 2001
From: RisingSunLight <risingsunlightdev@gmail.com>
Date: Sat, 12 Apr 2025 17:38:38 +0200
Subject: [PATCH 641/747] [TwigBundle] Enable `#[AsTwigFilter]`,
 `#[AsTwigFunction]` and `#[AsTwigTest]`

---
 quick_tour/the_architecture.rst | 19 ++++-------
 reference/attributes.rst        |  2 ++
 templates.rst                   | 56 +++++++++++++++++----------------
 3 files changed, 37 insertions(+), 40 deletions(-)

diff --git a/quick_tour/the_architecture.rst b/quick_tour/the_architecture.rst
index a323461885d..9f76dac3a23 100644
--- a/quick_tour/the_architecture.rst
+++ b/quick_tour/the_architecture.rst
@@ -159,29 +159,22 @@ Twig Extension & Autoconfiguration
 Thanks to Symfony's service handling, you can *extend* Symfony in many ways, like
 by creating an event subscriber or a security voter for complex authorization
 rules. Let's add a new filter to Twig called ``greet``. How? Create a class
-that extends ``AbstractExtension``::
+with your logic::
 
     // src/Twig/GreetExtension.php
     namespace App\Twig;
 
     use App\GreetingGenerator;
-    use Twig\Extension\AbstractExtension;
-    use Twig\TwigFilter;
+    use Twig\Attribute\AsTwigFilter;
 
-    class GreetExtension extends AbstractExtension
+    class GreetExtension
     {
         public function __construct(
             private GreetingGenerator $greetingGenerator,
         ) {
         }
 
-        public function getFilters(): array
-        {
-            return [
-                new TwigFilter('greet', [$this, 'greetUser']),
-            ];
-        }
-
+        #[AsTwigFilter('greet')]
         public function greetUser(string $name): string
         {
             $greeting =  $this->greetingGenerator->getRandomGreeting();
@@ -197,8 +190,8 @@ After creating just *one* file, you can use this immediately:
     {# templates/default/index.html.twig #}
     {# Will print something like "Hey Symfony!" #}
     <h1>{{ name|greet }}</h1>
-
-How does this work? Symfony notices that your class extends ``AbstractExtension``
+    
+How does this work? Symfony notices that your class uses a Twig attribute
 and so *automatically* registers it as a Twig extension. This is called autoconfiguration,
 and it works for *many* many things. Create a class and then extend a base class
 (or implement an interface). Symfony takes care of the rest.
diff --git a/reference/attributes.rst b/reference/attributes.rst
index a8399dafe28..7878446351c 100644
--- a/reference/attributes.rst
+++ b/reference/attributes.rst
@@ -123,6 +123,8 @@ Twig
 ~~~~
 
 * :ref:`Template <templates-template-attribute>`
+* :ref:`AsTwigFilter <templates-twig-filter-attribute>`
+* :ref:`AsTwigFunction <templates-twig-function-attribute>`
 
 Symfony UX
 ~~~~~~~~~~
diff --git a/templates.rst b/templates.rst
index c6312abb33c..bad63550786 100644
--- a/templates.rst
+++ b/templates.rst
@@ -1553,23 +1553,20 @@ as currency:
     {# pass in the 3 optional arguments #}
     {{ product.price|price(2, ',', '.') }}
 
-Create a class that extends ``AbstractExtension`` and fill in the logic::
+.. _templates-twig-filter-attribute:
+
+Create a class with a method that contains the filter logic, then add
+the ``#[AsTwigFilter]`` attribute to define the name and options of
+the Twig filter::
 
     // src/Twig/AppExtension.php
     namespace App\Twig;
 
-    use Twig\Extension\AbstractExtension;
-    use Twig\TwigFilter;
+    use Twig\Attribute\AsTwigFilter;
 
-    class AppExtension extends AbstractExtension
+    class AppExtension
     {
-        public function getFilters(): array
-        {
-            return [
-                new TwigFilter('price', [$this, 'formatPrice']),
-            ];
-        }
-
+        #[AsTwigFilter('price')]
         public function formatPrice(float $number, int $decimals = 0, string $decPoint = '.', string $thousandsSep = ','): string
         {
             $price = number_format($number, $decimals, $decPoint, $thousandsSep);
@@ -1579,24 +1576,19 @@ Create a class that extends ``AbstractExtension`` and fill in the logic::
         }
     }
 
-If you want to create a function instead of a filter, define the
-``getFunctions()`` method::
+.. _templates-twig-function-attribute:
+
+If you want to create a function instead of a filter, use the
+``#[AsTwigFunction]`` attribute::
 
     // src/Twig/AppExtension.php
     namespace App\Twig;
 
-    use Twig\Extension\AbstractExtension;
-    use Twig\TwigFunction;
+    use Twig\Attribute\AsTwigFunction;
 
-    class AppExtension extends AbstractExtension
+    class AppExtension
     {
-        public function getFunctions(): array
-        {
-            return [
-                new TwigFunction('area', [$this, 'calculateArea']),
-            ];
-        }
-
+        #[AsTwigFunction('area')]
         public function calculateArea(int $width, int $length): int
         {
             return $width * $length;
@@ -1608,6 +1600,16 @@ If you want to create a function instead of a filter, define the
     Along with custom filters and functions, you can also register
     `global variables`_.
 
+.. versionadded:: 7.3
+
+    Support for the ``#[AsTwigFilter]``, ``#[AsTwigFunction]`` and ``#[AsTwigTest]`` attributes was introduced in Symfony 7.3.
+    Previously, you had to extend the ``AbstractExtension`` class, and override the
+    ``getFilters()`` and ``getFunctions()`` methods.
+
+When using autoconfiguration, the tag ``twig.attribute_extension`` is added automatically
+when a Twig attribute is used on a method of a class. Otherwise, when autoconfiguration is not enabled,
+it needs to be added in the service definition.
+
 Register an Extension as a Service
 ..................................
 
@@ -1631,10 +1633,10 @@ this command to confirm that your new filter was successfully registered:
 Creating Lazy-Loaded Twig Extensions
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Including the code of the custom filters/functions in the Twig extension class
-is the simplest way to create extensions. However, Twig must initialize all
-extensions before rendering any template, even if the template doesn't use an
-extension.
+When using attributes to extend Twig, the services are initialized only when
+the functions or filters are used to render the template. But in case you use the
+classic approach by extending the ``AbstractExtension`` class, Twig initializes all the extensions before
+rendering any template, even if the extension is not used in the template.
 
 If extensions don't define dependencies (i.e. if you don't inject services in
 them) performance is not affected. However, if extensions define lots of complex

From a657538730c00bdf0ad8cbb6c87dfe5adbc67802 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 30 Apr 2025 13:43:06 +0200
Subject: [PATCH 642/747] Tweaks

---
 quick_tour/the_architecture.rst |  2 +-
 reference/attributes.rst        |  1 +
 templates.rst                   | 27 +++++++++++++++------------
 3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/quick_tour/the_architecture.rst b/quick_tour/the_architecture.rst
index 9f76dac3a23..fd7781c4944 100644
--- a/quick_tour/the_architecture.rst
+++ b/quick_tour/the_architecture.rst
@@ -191,7 +191,7 @@ After creating just *one* file, you can use this immediately:
     {# Will print something like "Hey Symfony!" #}
     <h1>{{ name|greet }}</h1>
     
-How does this work? Symfony notices that your class uses a Twig attribute
+How does this work? Symfony notices that your class uses the ``#[AsTwigFilter]`` attribute
 and so *automatically* registers it as a Twig extension. This is called autoconfiguration,
 and it works for *many* many things. Create a class and then extend a base class
 (or implement an interface). Symfony takes care of the rest.
diff --git a/reference/attributes.rst b/reference/attributes.rst
index 7878446351c..eb09f4aa6bc 100644
--- a/reference/attributes.rst
+++ b/reference/attributes.rst
@@ -125,6 +125,7 @@ Twig
 * :ref:`Template <templates-template-attribute>`
 * :ref:`AsTwigFilter <templates-twig-filter-attribute>`
 * :ref:`AsTwigFunction <templates-twig-function-attribute>`
+* ``AsTwigTest``
 
 Symfony UX
 ~~~~~~~~~~
diff --git a/templates.rst b/templates.rst
index bad63550786..530f98fcd5d 100644
--- a/templates.rst
+++ b/templates.rst
@@ -1555,8 +1555,8 @@ as currency:
 
 .. _templates-twig-filter-attribute:
 
-Create a class with a method that contains the filter logic, then add
-the ``#[AsTwigFilter]`` attribute to define the name and options of
+Create a regular PHP class with a method that contains the filter logic. Then,
+add the ``#[AsTwigFilter]`` attribute to define the name and options of
 the Twig filter::
 
     // src/Twig/AppExtension.php
@@ -1602,13 +1602,15 @@ If you want to create a function instead of a filter, use the
 
 .. versionadded:: 7.3
 
-    Support for the ``#[AsTwigFilter]``, ``#[AsTwigFunction]`` and ``#[AsTwigTest]`` attributes was introduced in Symfony 7.3.
-    Previously, you had to extend the ``AbstractExtension`` class, and override the
-    ``getFilters()`` and ``getFunctions()`` methods.
+    Support for the ``#[AsTwigFilter]``, ``#[AsTwigFunction]`` and ``#[AsTwigTest]``
+    attributes was introduced in Symfony 7.3. Previously, you had to extend the
+    ``AbstractExtension`` class, and override the ``getFilters()`` and ``getFunctions()``
+    methods.
 
-When using autoconfiguration, the tag ``twig.attribute_extension`` is added automatically
-when a Twig attribute is used on a method of a class. Otherwise, when autoconfiguration is not enabled,
-it needs to be added in the service definition.
+If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`,
+the :ref:`service autoconfiguration <services-autoconfigure>` feature will enable
+this class as a Twig extension. Otherwise, you need to define a service manually
+and :doc:`tag it </service_container/tags>` with the ``twig.attribute_extension`` tag.
 
 Register an Extension as a Service
 ..................................
@@ -1633,10 +1635,11 @@ this command to confirm that your new filter was successfully registered:
 Creating Lazy-Loaded Twig Extensions
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-When using attributes to extend Twig, the services are initialized only when
-the functions or filters are used to render the template. But in case you use the
-classic approach by extending the ``AbstractExtension`` class, Twig initializes all the extensions before
-rendering any template, even if the extension is not used in the template.
+When :ref:`using attributes to extend Twig <templates-twig-filter-attribute>`,
+the **Twig extensions are already lazy-loaded** and you don't have to do anything
+else. However, if your Twig extensions follow the **legacy approach** of extending
+the ``AbstractExtension`` class, Twig initializes all the extensions before
+rendering any template, even if they are not used.
 
 If extensions don't define dependencies (i.e. if you don't inject services in
 them) performance is not affected. However, if extensions define lots of complex

From 3ae4fec5293e8c0bd2a80f95c69a389e8e38ce4c Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 30 Apr 2025 13:45:14 +0200
Subject: [PATCH 643/747] Remove some unneeded extra space

---
 quick_tour/the_architecture.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/quick_tour/the_architecture.rst b/quick_tour/the_architecture.rst
index fd7781c4944..3b66570b3d3 100644
--- a/quick_tour/the_architecture.rst
+++ b/quick_tour/the_architecture.rst
@@ -190,7 +190,7 @@ After creating just *one* file, you can use this immediately:
     {# templates/default/index.html.twig #}
     {# Will print something like "Hey Symfony!" #}
     <h1>{{ name|greet }}</h1>
-    
+
 How does this work? Symfony notices that your class uses the ``#[AsTwigFilter]`` attribute
 and so *automatically* registers it as a Twig extension. This is called autoconfiguration,
 and it works for *many* many things. Create a class and then extend a base class

From c6a7fe6101319a3d2167013f46aa9bda56de5bc3 Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Sun, 4 May 2025 14:21:38 +0200
Subject: [PATCH 644/747] [Mailer][Mime] Refactor S/MIME encryption handling in
 SMimeEncryptionListener

---
 mailer.rst | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index d368048aec8..a562263f24c 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -1532,7 +1532,7 @@ encrypter that automatically applies to all outgoing messages:
         framework:
             mailer:
                 smime_encrypter:
-                    certificate: '%kernel.project_dir%/var/certificates/smime.crt'
+                    repository: app.my_smime_encrypter
 
     .. code-block:: xml
 
@@ -1549,7 +1549,7 @@ encrypter that automatically applies to all outgoing messages:
             <framework:config>
                 <framework:mailer>
                     <framework:smime-encrypter>
-                        <framework:certificate>%kernel.project_dir%/var/certificates/smime.crt</framework:certificate>
+                        <framework:repository>app.my_smime_encrypter</framework:repository>
                     </framework:smime-encrypter>
                 </framework:mailer>
             </framework:config>
@@ -1563,10 +1563,35 @@ encrypter that automatically applies to all outgoing messages:
         return static function (FrameworkConfig $framework): void {
             $mailer = $framework->mailer();
             $mailer->smimeEncrypter()
-                    ->certificate('%kernel.project_dir%/var/certificates/smime.crt')
+                    ->repository('app.my_smime_encrypter')
             ;
         };
 
+The ``repository`` option must be a service ID that implements
+:class:`Symfony\\Component\\Mailer\\EventListener\\SmimeCertificateRepositoryInterface`::
+
+    namespace App\Security;
+
+    use Symfony\Component\DependencyInjection\Attribute\Autowire;
+    use Symfony\Component\Mailer\EventListener\SmimeCertificateRepositoryInterface;
+
+    class LocalFileCertificateRepository implements SmimeCertificateRepositoryInterface
+    {
+        public function __construct(
+            #[Autowire(param: 'kernel.project_dir')]
+            private readonly string $projectDir
+        ){}
+
+        public function findCertificatePathFor(string $email): ?string
+        {
+            $hash = hash('sha256', strtolower(trim($email)));
+            $path = sprintf('%s/storage/%s.crt', $this->projectDir, $hash);
+
+            return file_exists($path) ? $path : null;
+        }
+    }
+
+
 .. versionadded:: 7.3
 
     Global message encryption configuration was introduced in Symfony 7.3.

From 454536494fc670d15c38df55290d76246cad6798 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@open.de>
Date: Mon, 5 May 2025 09:16:56 +0200
Subject: [PATCH 645/747] fix default value for the "collect_serializer_data"
 option

---
 reference/configuration/framework.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 56a7dfe54b1..b9ce997e128 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -2354,7 +2354,7 @@ Combine it with the ``collect`` option to enable/disable the profiler on demand:
 collect_serializer_data
 .......................
 
-**type**: ``boolean`` **default**: ``true``
+**type**: ``boolean`` **default**: ``false``
 
 When this option is ``true``, all normalizers and encoders are
 decorated by traceable implementations that collect profiling information about them.

From db23f1f95da99aa5ee5fae2f25a053f580bb7e1b Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 7 May 2025 09:07:54 +0200
Subject: [PATCH 646/747] Update some Symfony versions in bundle's best
 practices article

---
 bundles/best_practices.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/bundles/best_practices.rst b/bundles/best_practices.rst
index a588e8bb2fb..023b58af162 100644
--- a/bundles/best_practices.rst
+++ b/bundles/best_practices.rst
@@ -232,10 +232,10 @@ with Symfony Flex to install a specific Symfony version:
 
 .. code-block:: bash
 
-    # this requires Symfony 6.x for all Symfony packages
-    export SYMFONY_REQUIRE=6.*
+    # this requires Symfony 7.x for all Symfony packages
+    export SYMFONY_REQUIRE=7.*
     # alternatively you can run this command to update composer.json config
-    # composer config extra.symfony.require "6.*"
+    # composer config extra.symfony.require "7.*"
 
     # install Symfony Flex in the CI environment
     composer global config --no-plugins allow-plugins.symfony/flex true

From 2727ddee9427ca9b35e1996ac27c891277528d0c Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 6 May 2025 17:06:17 +0200
Subject: [PATCH 647/747] [Console] Update some contents of the Tree helper

---
 components/console/helpers/tree.rst | 100 ++++++++++++++++++++--------
 1 file changed, 73 insertions(+), 27 deletions(-)

diff --git a/components/console/helpers/tree.rst b/components/console/helpers/tree.rst
index 1161d00e942..b5839b74a26 100644
--- a/components/console/helpers/tree.rst
+++ b/components/console/helpers/tree.rst
@@ -96,25 +96,51 @@ The above code will output the following tree:
     └── templates
         └── base.html.twig
 
-Building and Rendering a Tree
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Building a Tree Programmatically
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-You can build a tree by creating a new instance of the
-:class:`Symfony\\Component\\Console\\Helper\\Tree` class and adding nodes to it::
+If you don't know the tree elements beforehand, you can build the tree programmatically
+by creating a new instance of the :class:`Symfony\\Component\\Console\\Helper\\Tree`
+class and adding nodes to it::
 
     use Symfony\Component\Console\Helper\TreeHelper;
     use Symfony\Component\Console\Helper\TreeNode;
 
-    $node = TreeNode::fromValues([
-        'Command',
-        'Controller' => [
-            'DefaultController.php',
-        ],
-        'Kernel.php',
-    ]);
-    $node->addChild('templates');
-    $node->addChild('tests');
+    $root = new TreeNode('my-project/');
+    // you can pass a string directly or create a TreeNode object
+    $root->addChild('src/');
+    $root->addChild(new TreeNode('templates/'));
+
+    // create nested structures by adding child nodes to other nodes
+    $testsNode = new TreeNode('tests/');
+    $functionalTestsNode = new TreeNode('Functional/');
+    $testsNode->addChild($functionalTestsNode);
+    $root->addChild(testsNode);
+
+    $tree = TreeHelper::createTree($io, $root);
+    $tree->render();
+
+This example outputs:
+
+.. code-block:: terminal
 
+    my-project/
+    ├── src/
+    ├── templates/
+    └── tests/
+        └── Functional/
+
+If you prefer, you can build the array of elements programmatically and then
+create and render the tree like this::
+
+    $tree = TreeHelper::createTree($io, null, $array);
+    $tree->render();
+
+You can also build part of the tree from an array and then add other nodes::
+
+    $node = TreeNode::fromValues($array);
+    $node->addChild('templates');
+    // ...
     $tree = TreeHelper::createTree($io, $node);
     $tree->render();
 
@@ -125,15 +151,13 @@ Built-in Tree Styles
 ~~~~~~~~~~~~~~~~~~~~
 
 The tree helper provides a few built-in styles that you can use to customize the
-output of the tree::
+output of the tree.
 
-    use Symfony\Component\Console\Helper\TreeStyle;
-    // ...
+**Default**::
 
-    $tree = TreeHelper::createTree($io, $node, [], TreeStyle::compact());
-    $tree->render();
+    TreeHelper::createTree($io, $node, [], TreeStyle::default());
 
-``TreeHelper::createTree($io, $node, [], TreeStyle::default())`` (`details`_)
+This outputs:
 
 .. code-block:: terminal
 
@@ -150,7 +174,11 @@ output of the tree::
     └── templates
        └── base.html.twig
 
-``TreeHelper::createTree($io, $node, [], TreeStyle::box())`` (`details`_)
+**Box**::
+
+    TreeHelper::createTree($io, $node, [], TreeStyle::box());
+
+This outputs:
 
 .. code-block:: terminal
 
@@ -167,7 +195,11 @@ output of the tree::
     ┗╸ templates
        ┗╸ base.html.twig
 
-``TreeHelper::createTree($io, $node, [], TreeStyle::doubleBox())`` (`details`_)
+**Double box**::
+
+    TreeHelper::createTree($io, $node, [], TreeStyle::doubleBox());
+
+This outputs:
 
 .. code-block:: terminal
 
@@ -184,7 +216,11 @@ output of the tree::
     ╚═ templates
       ╚═ base.html.twig
 
-``TreeHelper::createTree($io, $node, [], TreeStyle::compact())`` (`details`_)
+**Compact**::
+
+    TreeHelper::createTree($io, $node, [], TreeStyle::compact());
+
+This outputs:
 
 .. code-block:: terminal
 
@@ -201,7 +237,11 @@ output of the tree::
     └ templates
       └ base.html.twig
 
-``TreeHelper::createTree($io, $node, [], TreeStyle::light())`` (`details`_)
+**Light**::
+
+    TreeHelper::createTree($io, $node, [], TreeStyle::light());
+
+This outputs:
 
 .. code-block:: terminal
 
@@ -218,7 +258,11 @@ output of the tree::
     `-- templates
         `-- base.html.twig
 
-``TreeHelper::createTree($io, $node, [], TreeStyle::minimal())`` (`details`_)
+**Minimal**::
+
+    TreeHelper::createTree($io, $node, [], TreeStyle::minimal());
+
+This outputs:
 
 .. code-block:: terminal
 
@@ -235,7 +279,11 @@ output of the tree::
     . templates
       . base.html.twig
 
-``TreeHelper::createTree($io, $node, [], TreeStyle::rounded())`` (`details`_)
+**Rounded**::
+
+    TreeHelper::createTree($io, $node, [], TreeStyle::rounded());
+
+This outputs:
 
 .. code-block:: terminal
 
@@ -291,5 +339,3 @@ The above code will output the following tree:
     🔵 🟢 🟠 🟡 Kernel.php
     🔵 🟠 🟡 templates
     🔵 🔴 🟠 🟡 base.html.twig
-
-.. _`details`: https://github.com/symfony/symfony/blob/7.3/src/Symfony/Component/Console/Helper/TreeStyle.php

From a51f4a0fe27d05f9c1ad2f5963272d3cd3c7a73b Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 8 May 2025 09:15:54 +0200
Subject: [PATCH 648/747] Minor tweaks

---
 mailer.rst | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index a562263f24c..adc5beea7ab 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -1532,7 +1532,7 @@ encrypter that automatically applies to all outgoing messages:
         framework:
             mailer:
                 smime_encrypter:
-                    repository: app.my_smime_encrypter
+                    repository: App\Security\LocalFileCertificateRepository
 
     .. code-block:: xml
 
@@ -1549,7 +1549,7 @@ encrypter that automatically applies to all outgoing messages:
             <framework:config>
                 <framework:mailer>
                     <framework:smime-encrypter>
-                        <framework:repository>app.my_smime_encrypter</framework:repository>
+                        <framework:repository>App\Security\LocalFileCertificateRepository</framework:repository>
                     </framework:smime-encrypter>
                 </framework:mailer>
             </framework:config>
@@ -1558,17 +1558,20 @@ encrypter that automatically applies to all outgoing messages:
     .. code-block:: php
 
         // config/packages/mailer.php
+        use App\Security\LocalFileCertificateRepository;
         use Symfony\Config\FrameworkConfig;
 
         return static function (FrameworkConfig $framework): void {
             $mailer = $framework->mailer();
             $mailer->smimeEncrypter()
-                    ->repository('app.my_smime_encrypter')
+                    ->repository(LocalFileCertificateRepository::class)
             ;
         };
 
-The ``repository`` option must be a service ID that implements
-:class:`Symfony\\Component\\Mailer\\EventListener\\SmimeCertificateRepositoryInterface`::
+The ``repository`` option is the ID of a service that implements
+:class:`Symfony\\Component\\Mailer\\EventListener\\SmimeCertificateRepositoryInterface`.
+This interface requires only one method: ``findCertificatePathFor()``, which must
+return the file path to the certificate associated with the given email address::
 
     namespace App\Security;
 
@@ -1591,7 +1594,6 @@ The ``repository`` option must be a service ID that implements
         }
     }
 
-
 .. versionadded:: 7.3
 
     Global message encryption configuration was introduced in Symfony 7.3.

From 55217dcd8301cd51b023fa8f049af28b6d493c50 Mon Sep 17 00:00:00 2001
From: Dan Brown <ssddanbrown@googlemail.com>
Date: Sat, 1 Mar 2025 12:16:24 +0000
Subject: [PATCH 649/747] [Mailer] Document `require_tls` option

---
 mailer.rst | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/mailer.rst b/mailer.rst
index fd34a921b14..daf2c3428af 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -420,6 +420,29 @@ setting the ``auto_tls`` option to ``false`` in the DSN::
 
     This setting only works when the ``smtp://`` protocol is used.
 
+Ensure TLS
+~~~~~~~~~~
+
+You may want to ensure TLS is used, either directly or via ``STARTTLS``,
+for sending mail over SMTP regardless of other options set or SMTP server
+support. You can set TLS as required by calling ``setRequireTls(true)``
+on the ``EsmtpTransport`` instance, or by setting the ``require_tls`` option
+to ``true`` in the DSN::
+
+    $dsn = 'smtp://user:pass@10.0.0.25?require_tls=true';
+
+When TLS is set as required, a :class:`Symfony\\Component\\Mailer\\Exception\\TransportException`
+will be thrown if a TLS connection cannot be achieved during initial communications
+with the SMTP server.
+
+.. note::
+
+    This setting only works when the ``smtp://`` protocol is used.
+
+.. versionadded:: 7.3
+
+    The ``require_tls`` option was introduced in Symfony 7.3.
+
 Binding to IPv4 or IPv6
 ~~~~~~~~~~~~~~~~~~~~~~~
 

From 91aa72885001db55daebacfcdb56757fa41a3b8f Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 8 May 2025 10:06:47 +0200
Subject: [PATCH 650/747] Minor tweaks

---
 mailer.rst | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index e4a26c439e3..5e38bcd1722 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -423,21 +423,20 @@ setting the ``auto_tls`` option to ``false`` in the DSN::
 Ensure TLS
 ~~~~~~~~~~
 
-You may want to ensure TLS is used, either directly or via ``STARTTLS``,
-for sending mail over SMTP regardless of other options set or SMTP server
-support. You can set TLS as required by calling ``setRequireTls(true)``
-on the ``EsmtpTransport`` instance, or by setting the ``require_tls`` option
-to ``true`` in the DSN::
+You may want to ensure that TLS is used (either directly or via ``STARTTLS``)
+when sending mail over SMTP, regardless of other options or SMTP server support.
+To require TLS, call ``setRequireTls(true)`` on the ``EsmtpTransport`` instance,
+or set the ``require_tls`` option to ``true`` in the DSN::
 
     $dsn = 'smtp://user:pass@10.0.0.25?require_tls=true';
 
-When TLS is set as required, a :class:`Symfony\\Component\\Mailer\\Exception\\TransportException`
-will be thrown if a TLS connection cannot be achieved during initial communications
+When TLS is required, a :class:`Symfony\\Component\\Mailer\\Exception\\TransportException`
+is thrown if a TLS connection cannot be established during the initial communication
 with the SMTP server.
 
 .. note::
 
-    This setting only works when the ``smtp://`` protocol is used.
+    This setting only applies when using the ``smtp://`` protocol.
 
 .. versionadded:: 7.3
 

From ac6a2587b2e32adf557aaccf86f040f8668d4041 Mon Sep 17 00:00:00 2001
From: Florent Morselli <florent.morselli@spomky-labs.com>
Date: Thu, 8 May 2025 13:54:11 +0200
Subject: [PATCH 651/747] Introduce user identifier normalization for enhanced
 consistency

Added support for normalizing user identifiers in Symfony 7.3 to ensure consistent comparison and storage. Updated documentation with implementation examples, highlighting best practices like converting identifiers to lowercase and handling various formats. This improvement reduces the risk of duplicates and improves reliability in user authentication.
---
 security/custom_authenticator.rst | 98 ++++++++++++++++++++++++++++++-
 1 file changed, 95 insertions(+), 3 deletions(-)

diff --git a/security/custom_authenticator.rst b/security/custom_authenticator.rst
index 8b2ec9d7f34..5877194ab4e 100644
--- a/security/custom_authenticator.rst
+++ b/security/custom_authenticator.rst
@@ -209,13 +209,20 @@ requires a user and some sort of "credentials" (e.g. a password).
 Use the
 :class:`Symfony\\Component\\Security\\Http\\Authenticator\\Passport\\Badge\\UserBadge`
 to attach the user to the passport. The ``UserBadge`` requires a user
-identifier (e.g. the username or email), which is used to load the user
-using :ref:`the user provider <security-user-providers>`::
+identifier (e.g. the username or email)::
 
     use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
 
     // ...
-    $passport = new Passport(new UserBadge($email), $credentials);
+    $passport = new Passport(new UserBadge($userIdentifier), $credentials);
+
+User Identifier
+~~~~~~~~~~~~~~~
+
+The user identifier is a unique string that identifies the user. It is used
+to load the user using :ref:`the user provider <security-user-providers>`.
+This identifier is often something like the user's email address or username,
+but it could be any unique value associated with the user.
 
 .. note::
 
@@ -255,6 +262,91 @@ using :ref:`the user provider <security-user-providers>`::
             }
         }
 
+It is a good practice to normalize the user identifier before using it.
+For example, this ensures that variations such as "john.doe", "John.Doe",
+or "JOHN.DOE" refer to the same user.
+Normalization can include converting the identifier to lowercase
+and trimming unnecessary spaces.
+You can optionally pass a user identifier normalizer as third argument to the
+``UserBadge``. This callable receives the ``$userIdentifier``
+and must return a normalized user identifier as a string.
+
+.. versionadded:: 7.3
+
+    The support of the user identifier normalizer was introduced in Symfony 7.3.
+
+For instance, the example below uses a normalizer that converts usernames to a normalized, ASCII-only, lowercase format,
+suitable for consistent comparison and storage.
+
+    // src/Security/NormalizedUserBadge.php
+    namespace App\Security;
+
+    use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
+    use Symfony\Component\String\UnicodeString;
+    use function Symfony\Component\String\u;
+
+    final class NormalizedUserBadge extends UserBadge
+    {
+        public function __construct(string $identifier)
+        {
+            $callback = static fn (string $identifier) => u($identifier)->normalize(UnicodeString::NFKC)->ascii()->lower()->toString();
+
+            parent::__construct($identifier, null, $callback);
+        }
+    }
+
+    // src/Security/PasswordAuthenticator.php
+    namespace App\Security;
+
+    final class PasswordAuthenticator extends AbstractLoginFormAuthenticator
+    {
+        // Simplified for brievety
+        public function authenticate(Request $request): Passport
+        {
+            $username = (string) $request->request->get('username', '');
+            $password = (string) $request->request->get('password', '');
+
+            $request->getSession()
+                ->set(SecurityRequestAttributes::LAST_USERNAME, $username);
+
+            return new Passport(
+                new NormalizedUserBadge($username),
+                new PasswordCredentials($password),
+                [
+                    //All other useful badges
+                ]
+            );
+        }
+    }
+
+.. note::
+
+    For example, Google treats the following email addresses as equivalent:
+    ``john.doe@gmail.com``, ``j.hon.d.oe@gmail.com``, and ``johndoe@gmail.com``.
+    This is because Google applies normalization rules that remove dots
+    and convert the address to lowercase (though behavior varies across services).
+
+.. note::
+
+    In enterprise environments, a user may authenticate using different formats
+    of their identifier, such as:
+
+    - ``john.doe@acme.com``
+    - ``acme.com\jdoe``
+    - ``https://acme.com/+jdoe``
+    - ``acct:jdoe@acme.com``
+
+    Applying normalization (e.g., trimming, lowercasing, or format unification)
+    helps ensure consistent identity recognition across systems and prevents
+    duplicates caused by format variations.
+
+User Credential
+~~~~~~~~~~~~~~~
+
+The user credential is used to authenticate the user i.e. to verify
+the validity of the provided information (such as a password, an API token,
+or other custom credentials).
+
 The following credential classes are supported by default:
 
 :class:`Symfony\\Component\\Security\\Http\\Authenticator\\Passport\\Credentials\\PasswordCredentials`

From 9ea15853923979d457e45674bc8f4ab9c3ed306f Mon Sep 17 00:00:00 2001
From: soyuka <soyuka@users.noreply.github.com>
Date: Thu, 24 Oct 2024 21:04:38 +0200
Subject: [PATCH 652/747] [ObjectMapper] Add component

---
 object-mapper.rst | 729 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 729 insertions(+)
 create mode 100644 object-mapper.rst

diff --git a/object-mapper.rst b/object-mapper.rst
new file mode 100644
index 00000000000..f46ab732110
--- /dev/null
+++ b/object-mapper.rst
@@ -0,0 +1,729 @@
+Object Mapper
+=============
+
+Symfony provides a mapper component to transform a given object into another one,
+simplifying tasks like converting DTOs (Data Transfer Objects) to entities or
+vice-versa. It may also be useful when decoupling API input/output from internal
+models helping with legacy code or hexagonal architectures implementations.
+
+.. versionadded:: 7.2
+
+    The ObjectMapper component is experimental. Experimental features are not
+    covered by the backward compatibility promise.
+
+Installation
+------------
+
+Run this command to install the ``object-mapper`` component before using it:
+
+.. code-block:: terminal
+
+    $ composer require symfony/object-mapper
+
+Using the ObjectMapper
+----------------------
+
+Once installed, the object mapper service can be injected into any service or
+controller where you need it:
+
+::
+
+    // src/Controller/UserController.php
+    namespace App\Controller;
+
+    use App\Dto\UserInput;
+    use App\Entity\User;
+    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+    use Symfony\Component\HttpFoundation\Response;
+    use Symfony\Component\ObjectMapper\ObjectMapperInterface;
+
+    class UserController extends AbstractController
+    {
+        public function updateUser(UserInput $userInput, ObjectMapperInterface $objectMapper): Response
+        {
+            $user = new User();
+            // Map properties from UserInput to User
+            $objectMapper->map($userInput, $user);
+
+            // ... persist $user and return response
+            return new Response('User updated!');
+        }
+    }
+
+Basic Mapping
+-------------
+
+The core functionality is provided by the ``map()`` method. It takes a source
+object and maps its properties onto a target. The target can be either a
+class name (a new instance will be created) or an existing object instance.
+
+**Mapping to a New Object:**
+
+Provide the target class name as the second argument:
+
+::
+
+    use App\Dto\ProductInput;
+    use App\Entity\Product;
+    use Symfony\Component\ObjectMapper\ObjectMapper;
+
+    $productInput = new ProductInput();
+    $productInput->name = 'Wireless Mouse';
+    $productInput->sku = 'WM-1024';
+
+    $mapper = new ObjectMapper();
+    // Creates a new Product instance and maps properties from $productInput
+    $product = $mapper->map($productInput, Product::class);
+
+    // $product is now an instance of Product
+    // with $product->name = 'Wireless Mouse' and $product->sku = 'WM-1024'
+
+**Mapping to an Existing Object:**
+
+Provide an existing object instance as the second argument to update it:
+
+::
+
+    use App\Dto\ProductUpdateInput;
+    use App\Entity\Product;
+    use Symfony\Component\ObjectMapper\ObjectMapper;
+
+    $product = $productRepository->find(1);
+
+    $updateInput = new ProductUpdateInput();
+    $updateInput->price = 99.99;
+
+    $mapper = new ObjectMapper();
+    // Updates the existing $product instance
+    $mapper->map($updateInput, $product);
+
+    // $product->price is now 99.99
+
+**Mapping from ``stdClass``:**
+
+The source object can also be an instance of ``stdClass``:
+
+::
+
+    use App\Entity\Product;
+    use Symfony\Component\ObjectMapper\ObjectMapper;
+
+    $productData = new \stdClass();
+    $productData->name = 'Keyboard';
+    $productData->sku = 'KB-001';
+
+    $mapper = new ObjectMapper();
+    $product = $mapper->map($productData, Product::class);
+
+    // $product is an instance of Product with properties mapped from $productData
+
+Configuring Mapping with Attributes
+-----------------------------------
+
+The ObjectMapper uses PHP attributes to configure the mapping process. The
+primary attribute is :class:`Symfony\\Component\\ObjectMapper\\Attribute\\Map`.
+
+**Defining the Default Target Class:**
+
+Apply ``#[Map]`` to the source class to define its default mapping target:
+
+::
+
+    // src/Dto/ProductInput.php
+    namespace App\Dto;
+
+    use App\Entity\Product;
+    use Symfony\Component\ObjectMapper\Attribute\Map;
+
+    #[Map(target: Product::class)]
+    class ProductInput
+    {
+        public string $name = '';
+        public string $sku = '';
+    }
+
+    // Now you can call map() without the second argument if ProductInput is the source:
+    $mapper = new ObjectMapper();
+    $product = $mapper->map($productInput); // Maps to Product automatically
+
+**Configuring Property Mapping:**
+
+Apply ``#[Map]`` to properties to customize their mapping behavior.
+
+* ``target``: Specifies the name of the property in the target object.
+* ``source``: Specifies the name of the property in the source object (useful
+    when mapping is defined on the target, see below).
+* ``if``: Defines a condition for mapping the property.
+* ``transform``: Applies a transformation to the value before mapping.
+
+::
+
+    // src/Dto/OrderInput.php
+    namespace App\Dto;
+
+    use App\Entity\Order;
+    use Symfony\Component\ObjectMapper\Attribute\Map;
+
+    #[Map(target: Order::class)]
+    class OrderInput
+    {
+        // Map 'customerEmail' from source to 'email' in target
+        #[Map(target: 'email')]
+        public string $customerEmail = '';
+
+        // Do not map this property at all
+        #[Map(if: false)]
+        public string $internalNotes = '';
+
+        // Only map 'discountCode' if it's a non-empty string
+        #[Map(if: 'strlen')] // Uses the built-in strlen function as a condition
+        public ?string $discountCode = null;
+    }
+
+By default, if a property exists in the source but not in the target, it's
+ignored. If a property exists in both and has no ``#[Map]`` attribute, it's
+mapped directly if the names match.
+
+**Conditional Mapping with Services:**
+
+For complex conditions, you can use a dedicated service implementing
+:class:`Symfony\\Component\\ObjectMapper\\ConditionCallableInterface`. The service
+name (its class name by default) is passed to the ``if`` parameter:
+
+::
+
+    // src/ObjectMapper/IsShippableCondition.php
+    namespace App\ObjectMapper;
+
+    use App\Dto\OrderInput;
+    use App\Entity\Order; // Target type hint
+    use Symfony\Component\ObjectMapper\ConditionCallableInterface;
+
+    /**
+     * @implements ConditionCallableInterface<OrderInput, Order>
+     */
+    final class IsShippableCondition implements ConditionCallableInterface
+    {
+        public function __invoke(mixed $value, object $source, ?object $target): bool
+        {
+            // Example: Only map shipping address if order total is above 50
+            return $source->total > 50;
+        }
+    }
+
+::
+
+    // src/Dto/OrderInput.php
+    namespace App\Dto;
+
+    use App\Entity\Order;
+    use App\ObjectMapper\IsShippableCondition;
+    use Symfony\Component\ObjectMapper\Attribute\Map;
+
+    #[Map(target: Order::class)]
+    class OrderInput
+    {
+        public float $total = 0.0;
+
+        #[Map(if: IsShippableCondition::class)]
+        public ?string $shippingAddress = null;
+    }
+
+For this to work, ``IsShippableCondition`` must be registered as a service.
+
+.. _object_mapper-conditional-property-target:
+
+**Conditional Property Mapping based on Target:**
+
+When a source class can be mapped to multiple target classes, you might want
+to map a specific property only when mapping to a particular target. You can
+achieve this using the :class:`Symfony\\Component\\ObjectMapper\\Condition\\TargetClass`
+condition within the ``if`` parameter on a property's ``#[Map]`` attribute.
+
+This is useful for creating different representations (e.g., public vs. admin)
+from the same source object, offering an alternative to serialization groups.
+
+::
+
+    // src/Entity/User.php
+    namespace App\Entity;
+
+    use App\Dto\AdminUserProfile;
+    use App\Dto\PublicUserProfile;
+    use Symfony\Component\ObjectMapper\Attribute\Map;
+    use Symfony\Component\ObjectMapper\Condition\TargetClass;
+
+    // This User entity can be mapped to two different DTOs
+    #[Map(target: PublicUserProfile::class)]
+    #[Map(target: AdminUserProfile::class)]
+    class User
+    {
+        // Map 'lastLoginIp' to 'ipAddress' ONLY when the target is AdminUserProfile
+        #[Map(target: 'ipAddress', if: new TargetClass(AdminUserProfile::class))]
+        public ?string $lastLoginIp = '192.168.1.100';
+
+        // Map 'registrationDate' to 'memberSince' for both targets
+        #[Map(target: 'memberSince')]
+        public \DateTimeImmutable $registrationDate;
+
+        public function __construct() {
+            $this->registrationDate = new \DateTimeImmutable();
+        }
+    }
+
+    // src/Dto/PublicUserProfile.php
+    namespace App\Dto;
+    class PublicUserProfile {
+        public \DateTimeImmutable $memberSince;
+        // No $ipAddress property here
+    }
+
+    // src/Dto/AdminUserProfile.php
+    namespace App\Dto;
+    class AdminUserProfile {
+        public \DateTimeImmutable $memberSince;
+        public ?string $ipAddress = null; // Mapped from lastLoginIp
+    }
+
+    // Usage:
+    $user = new User();
+    $mapper = new ObjectMapper();
+
+    $publicProfile = $mapper->map($user, PublicUserProfile::class);
+    // No IP address available
+
+    $adminProfile = $mapper->map($user, AdminUserProfile::class);
+    // $adminProfile->ipAddress = '192.168.1.100'
+
+Transforming Values
+-------------------
+
+Use the ``transform`` option within ``#[Map]`` to modify a value before it's
+assigned to the target property. The value can be a callable (like a built-in
+PHP function name, a static method, or an anonymous function) or a service
+implementing :class:`Symfony\\Component\\ObjectMapper\\TransformCallableInterface`.
+
+**Using Callables:**
+
+::
+
+    // src/Dto/ProductInput.php
+    namespace App\Dto;
+
+    use App\Entity\Product;
+    use App\Util\PriceFormatter;
+    use Symfony\Component\ObjectMapper\Attribute\Map;
+
+    #[Map(target: Product::class)]
+    class ProductInput
+    {
+        // Use a static method from another class for formatting
+        #[Map(target: 'displayPrice', transform: [PriceFormatter::class, 'format'])]
+        public float $price = 0.0;
+
+        // Can also use simple built-ins
+        #[Map(transform: 'intval')]
+        public string $stockLevel = '100';
+    }
+
+::
+
+    // src/Util/PriceFormatter.php
+    namespace App\Util;
+    class PriceFormatter {
+        public static function format(float $value, object $source): string {
+            return number_format($value, 2, '.', '');
+        }
+    }
+
+**Using Transformer Services:**
+
+Similar to conditions, complex transformations can be encapsulated in services
+implementing :class:`Symfony\\Component\\ObjectMapper\\TransformCallableInterface`.
+
+::
+
+    // src/ObjectMapper/FullNameTransformer.php
+    namespace App\ObjectMapper;
+
+    use App\Dto\UserInput;
+    use App\Entity\User;
+    use Symfony\Component\ObjectMapper\TransformCallableInterface;
+
+    /**
+     * @implements TransformCallableInterface<UserInput, User>
+     */
+    final class FullNameTransformer implements TransformCallableInterface
+    {
+        public function __invoke(mixed $value, object $source, ?object $target): mixed
+        {
+            return trim($source->firstName . ' ' . $source->lastName);
+        }
+    }
+
+::
+
+    // src/Dto/UserInput.php
+    namespace App\Dto;
+
+    use App\Entity\User;
+    use App\ObjectMapper\FullNameTransformer;
+    use Symfony\Component\ObjectMapper\Attribute\Map;
+
+    #[Map(target: User::class)]
+    class UserInput
+    {
+        // This property's value will be generated by the transformer
+        #[Map(target: 'fullName', transform: FullNameTransformer::class)]
+        public string $firstName = '';
+
+        public string $lastName = '';
+    }
+
+**Class-Level Transformation:**
+
+You can apply a ``transform`` callable at the class level. This callable is
+executed *after* the target object is initially created (if the target is a
+class name we use ``newInstanceWithoutConstructor``) but *before* properties
+are mapped. Its responsibility is often to return a correctly initialized
+instance, potentially replacing the one created by the mapper.
+The returned value *must* be an object of the target type or else an
+exception will be thrown.
+
+::
+
+    // src/Dto/LegacyUserData.php
+    namespace App\Dto;
+
+    use App\Entity\User;
+    use Symfony\Component\ObjectMapper\Attribute\Map;
+
+    // Use a static factory method on the target User class for instantiation
+    #[Map(target: User::class, transform: [User::class, 'createFromLegacy'])]
+    class LegacyUserData
+    {
+        public int $userId = 0;
+        public string $name = '';
+    }
+
+::
+
+    // src/Entity/User.php
+    namespace App\Entity;
+    class User {
+        public string $name = '';
+        private int $legacyId = 0;
+
+        private function __construct() {} // Private constructor
+
+        public static function createFromLegacy(mixed $value, object $source): self
+        {
+            // $value is the initially created (empty) User object
+            // $source is the LegacyUserData object
+            $user = new self();
+            $user->legacyId = $source->userId;
+            // Property mapping will happen *after* this method returns $user
+            return $user;
+        }
+    }
+
+Mapping Multiple Targets
+------------------------
+
+A source class can be configured to map to multiple different target classes.
+Apply the ``#[Map]`` attribute multiple times at the class level, typically
+using the ``if`` condition to determine which target is appropriate based on the
+source object's state or other logic.
+
+::
+
+    // src/Dto/EventInput.php
+    namespace App\Dto;
+
+    use App\Entity\OnlineEvent;
+    use App\Entity\PhysicalEvent;
+    use Symfony\Component\ObjectMapper\Attribute\Map;
+
+    #[Map(target: OnlineEvent::class, if: [self::class, 'isOnline'])]
+    #[Map(target: PhysicalEvent::class, if: [self::class, 'isPhysical'])]
+    class EventInput
+    {
+        public string $type = 'online'; // e.g., 'online' or 'physical'
+        public string $title = '';
+
+        /**
+         * In class-level conditions, $value is null.
+         */
+        public static function isOnline(?mixed $value, object $source): bool
+        {
+            return $source->type === 'online';
+        }
+
+        public static function isPhysical(?mixed $value, object $source): bool
+        {
+            return $source->type === 'physical';
+        }
+    }
+
+    // src/Entity/OnlineEvent.php / PhysicalEvent.php ...
+
+    // Usage:
+    $eventInput = new EventInput();
+    $eventInput->type = 'physical';
+    $mapper = new ObjectMapper();
+    $event = $mapper->map($eventInput); // Automatically maps to PhysicalEvent
+
+Mapping Based on Target Properties (Source Mapping)
+---------------------------------------------------
+
+Sometimes, it's more convenient to define the mapping on the *target* class,
+specifying where its properties should come from in the *source* class. This is
+done using the ``source`` parameter within the ``#[Map]`` attribute on the target's
+properties.
+
+Note that if both the ``source`` and the ``target`` classes define the ``#[Map]``
+attribute, the ``source`` takes precedence.
+
+::
+
+    // src/Api/Payload.php - Represents data from an external API
+    namespace App\Api;
+    class Payload
+    {
+        public string $product_name = ''; // Source property name uses snake_case
+        public float $price_amount = 0.0;
+    }
+
+::
+
+    // src/Entity/Product.php - Our application's entity
+    namespace App\Entity;
+
+    use App\Api\Payload;
+    use Symfony\Component\ObjectMapper\Attribute\Map;
+
+    // Define that Product can be mapped *from* Payload
+    #[Map(source: Payload::class)]
+    class Product
+    {
+        // Define where 'name' should get its value from in the Payload source
+        #[Map(source: 'product_name')]
+        public string $name = ''; // Target property uses camelCase
+
+        // Define where 'price' should get its value from
+        #[Map(source: 'price_amount')]
+        public float $price = 0.0;
+    }
+
+    // Usage:
+    $payload = new Payload();
+    $payload->product_name = 'Super Widget';
+    $payload->price_amount = 123.45;
+
+    $mapper = new ObjectMapper();
+    // Map *from* the payload *to* the Product class
+    $product = $mapper->map($payload, Product::class);
+
+    // $product->name = 'Super Widget'
+    // $product->price = 123.45
+
+When using ``source`` mapping, the ``ObjectMapper`` detects this configuration if
+the source object itself doesn't have ``#[Map]`` attributes pointing outwards. It
+then reads the ``#[Map(source: ...)]`` attributes from the target class instead.
+
+Handling Recursion
+------------------
+
+The ObjectMapper automatically handles recursive relationships. If an object graph
+contains cycles (e.g., a ``User`` has a ``manager`` which is another ``User``,
+who might manage the first user), the mapper will reuse the already mapped target
+instances to avoid infinite loops.
+
+::
+
+    // src/Entity/User.php
+    namespace App\Entity;
+    use App\Dto\UserDto;
+    use Symfony\Component\ObjectMapper\Attribute\Map;
+
+    #[Map(target: UserDto::class)]
+    class User {
+        public string $name = '';
+        public ?User $manager = null;
+    }
+
+::
+
+    // src/Dto/UserDto.php
+    namespace App\Dto;
+    use Symfony\Component\ObjectMapper\Attribute\Map;
+
+    #[Map(source: \App\Entity\User::class)] // Can also define mapping here
+    class UserDto {
+        public string $name = '';
+        public ?UserDto $manager = null;
+    }
+
+    // Usage:
+    $manager = new User();
+    $manager->name = 'Alice';
+    $employee = new User();
+    $employee->name = 'Bob';
+    $employee->manager = $manager;
+    // Manager's manager is the employee:
+    $manager->manager = $employee;
+
+    $mapper = new ObjectMapper();
+    $employeeDto = $mapper->map($employee, UserDto::class);
+
+    // Recursion is handled correctly:
+    // $employeeDto->name === 'Bob'
+    // $employeeDto->manager->name === 'Alice'
+    // $employeeDto->manager->manager === $employeeDto
+
+Custom Mapping Logic (MapStruct-like Approach)
+----------------------------------------------
+
+For very complex mapping scenarios or if you prefer separating mapping rules from
+your DTOs/Entities, you can implement a custom mapping strategy using the
+:class:`Symfony\\Component\\ObjectMapper\\Metadata\\ObjectMapperMetadataFactoryInterface`.
+This allows defining mapping rules within dedicated "mapper" services, similar
+to the approach used by libraries like MapStruct in the Java ecosystem.
+
+First, create your custom metadata factory. The following example reads mapping
+rules defined via ``#[Map]`` attributes on a dedicated mapper *service* class,
+specifically on its ``map`` method for property mappings and on the class itself
+for the source-to-target relationship:
+
+::
+
+    namespace App\ObjectMapper\Metadata;
+
+    use Symfony\Component\ObjectMapper\Attribute\Map;
+    use Symfony\Component\ObjectMapper\Metadata\Mapping;
+    use Symfony\Component\ObjectMapper\Metadata\ObjectMapperMetadataFactoryInterface;
+    use Symfony\Component\ObjectMapper\ObjectMapperInterface;
+
+    /**
+     * A Metadata factory that implements basics similar to MapStruct.
+     * Reads mapping configuration from attributes on a dedicated mapper service.
+     */
+    final class MapStructMapperMetadataFactory implements ObjectMapperMetadataFactoryInterface
+    {
+        /**
+         * @param class-string<ObjectMapperInterface> $mapperClass The FQCN of the mapper service class
+         */
+        public function __construct(private readonly string $mapperClass)
+        {
+            if (!is_a($this->mapperClass, ObjectMapperInterface::class, true)) {
+                throw new \RuntimeException(sprintf('Mapper class "%s" must implement "%s".', $this->mapperClass, ObjectMapperInterface::class));
+            }
+        }
+
+        public function create(object $object, ?string $property = null, array $context = []): array
+        {
+            try {
+                $refl = new \ReflectionClass($this->mapperClass);
+            } catch (\ReflectionException $e) {
+                throw new \RuntimeException("Failed to reflect mapper class: " . $e->getMessage(), 0, $e);
+            }
+
+            $mapConfigs = [];
+            $sourceIdentifier = $property ?? $object::class;
+
+            // Read attributes from the map method (for property mapping) or the class (for class mapping)
+            $attributesSource = $property ? $refl->getMethod('map') : $refl;
+            foreach ($attributesSource->getAttributes(Map::class, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
+                $map = $attribute->newInstance();
+
+                // Check if the attribute's source matches the current property or source class
+                if ($map->source === $sourceIdentifier) {
+                    $mapConfigs[] = new Mapping($map->target, $map->source, $map->if, $map->transform);
+                }
+            }
+
+            // If it's a property lookup and no specific mapping was found, map to the same property
+            if ($property && empty($mapConfigs)) {
+                $mapConfigs[] = new Mapping(target: $property, source: $property);
+            }
+
+            return $mapConfigs;
+        }
+    }
+
+Next, define your mapper service class. This class implements
+``ObjectMapperInterface`` but typically delegates the actual mapping back to a
+standard ``ObjectMapper`` instance configured with the custom metadata factory.
+Mapping rules are defined using ``#[Map]`` attributes on this class and its
+``map`` method:
+
+::
+
+    namespace App\ObjectMapper;
+
+    use App\Dto\LegacyUser;
+    use App\Dto\UserDto;
+    use App\ObjectMapper\Metadata\MapStructMapperMetadataFactory;
+    use Symfony\Component\ObjectMapper\Attribute\Map;
+    use Symfony\Component\ObjectMapper\ObjectMapper;
+    use Symfony\Component\ObjectMapper\ObjectMapperInterface;
+
+    // Define the source-to-target mapping at the class level
+    #[Map(source: LegacyUser::class, target: UserDto::class)]
+    class LegacyUserMapper implements ObjectMapperInterface
+    {
+        private readonly ObjectMapperInterface $objectMapper;
+
+        // Inject the standard ObjectMapper or necessary dependencies
+        public function __construct(?ObjectMapperInterface $objectMapper = null)
+        {
+            // Create an ObjectMapper instance configured with *this* mapper's rules
+            $metadataFactory = new MapStructMapperMetadataFactory(self::class);
+            $this->objectMapper = $objectMapper ?? new ObjectMapper($metadataFactory);
+        }
+
+        // Define property-specific mapping rules on the map method
+        #[Map(source: 'fullName', target: 'name')] // Map LegacyUser::fullName to UserDto::name
+        #[Map(source: 'creationTimestamp', target: 'registeredAt', transform: [\DateTimeImmutable::class, 'createFromFormat'])]
+        #[Map(source: 'status', if: false)] // Ignore the 'status' property from LegacyUser
+        public function map(object $source, object|string|null $target = null): object
+        {
+            // Delegate the actual mapping to the configured ObjectMapper
+            return $this->objectMapper->map($source, $target);
+        }
+    }
+
+Finally, use your custom mapper service:
+
+::
+
+    use App\Dto\LegacyUser;
+    use App\ObjectMapper\LegacyUserMapper;
+
+    $legacyUser = new LegacyUser();
+    $legacyUser->fullName = 'Jane Doe';
+    $legacyUser->status = 'active'; // This will be ignored
+
+    // Instantiate your custom mapper service
+    $mapperService = new LegacyUserMapper();
+
+    // Use the map method of your service
+    $userDto = $mapperService->map($legacyUser); // Target (UserDto) is inferred from #[Map] on LegacyUserMapper
+
+This approach keeps mapping logic centralized within dedicated services, which
+can be beneficial for complex applications or when adhering to specific architectural
+patterns.
+
+Advanced Configuration
+----------------------
+
+The ``ObjectMapper`` constructor accepts optional arguments for further customization:
+
+* ``ObjectMapperMetadataFactoryInterface $metadataFactory``: Allows providing a custom metadata factory, as shown in the MapStruct example. Defaults to :class:`Symfony\\Component\\ObjectMapper\\Metadata\\ReflectionObjectMapperMetadataFactory`, which reads ``#[Map]`` attributes directly from source/target classes.
+* ``?PropertyAccessorInterface $propertyAccessor``: An instance of the PropertyAccess component to customize how properties are read from the source and written to the target. Useful for accessing private properties or using getters/setters.
+* ``?ContainerInterface $transformCallableLocator``: A PSR-11 container (service locator) used to resolve service IDs provided in the ``transform`` option of ``#[Map]``.
+* ``?ContainerInterface $conditionCallableLocator``: A PSR-11 container used to resolve service IDs provided in the ``if`` option of ``#[Map]``.
+
+When using the ``ObjectMapperInterface`` service provided by the Symfony framework,
+these dependencies (like the property accessor and service locators for callables)
+are typically configured automatically via the service container.

From 5b70521d762c1215f435e630e9cea30a7a9b1b3f Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 9 May 2025 10:29:14 +0200
Subject: [PATCH 653/747] Tweaks and fixes

---
 object-mapper.rst => object_mapper.rst | 399 +++++++++++++------------
 1 file changed, 204 insertions(+), 195 deletions(-)
 rename object-mapper.rst => object_mapper.rst (62%)

diff --git a/object-mapper.rst b/object_mapper.rst
similarity index 62%
rename from object-mapper.rst
rename to object_mapper.rst
index f46ab732110..fe7db2365cf 100644
--- a/object-mapper.rst
+++ b/object_mapper.rst
@@ -1,32 +1,31 @@
 Object Mapper
 =============
 
-Symfony provides a mapper component to transform a given object into another one,
-simplifying tasks like converting DTOs (Data Transfer Objects) to entities or
-vice-versa. It may also be useful when decoupling API input/output from internal
-models helping with legacy code or hexagonal architectures implementations.
+.. versionadded:: 7.3
 
-.. versionadded:: 7.2
+    The ObjectMapper component was introduced in Symfony 7.3 as an
+    :doc:`experimental feature </contributing/code/experimental>`.
 
-    The ObjectMapper component is experimental. Experimental features are not
-    covered by the backward compatibility promise.
+This component transforms one object into another, simplifying tasks such as
+converting DTOs (Data Transfer Objects) into entities or vice versa. It can also
+be helpful when decoupling API input/output from internal models, particularly
+when working with legacy code or implementing hexagonal architectures.
 
 Installation
 ------------
 
-Run this command to install the ``object-mapper`` component before using it:
+Run this command to install the component before using it:
 
 .. code-block:: terminal
 
     $ composer require symfony/object-mapper
 
-Using the ObjectMapper
-----------------------
-
-Once installed, the object mapper service can be injected into any service or
-controller where you need it:
+Usage
+-----
 
-::
+The object mapper service will be :doc:`autowired </service_container/autowiring>`
+automatically in controllers or services when type-hinting for
+:class:`Symfony\\Component\\ObjectMapper\\ObjectMapperInterface`::
 
     // src/Controller/UserController.php
     namespace App\Controller;
@@ -53,15 +52,14 @@ controller where you need it:
 Basic Mapping
 -------------
 
-The core functionality is provided by the ``map()`` method. It takes a source
-object and maps its properties onto a target. The target can be either a
-class name (a new instance will be created) or an existing object instance.
+The core functionality is provided by the ``map()`` method. It accepts a
+source object and maps its properties to a target. The target can either be
+a class name (to create a new instance) or an existing object (to update it).
 
-**Mapping to a New Object:**
+Mapping to a New Object
+~~~~~~~~~~~~~~~~~~~~~~~
 
-Provide the target class name as the second argument:
-
-::
+Provide the target class name as the second argument::
 
     use App\Dto\ProductInput;
     use App\Entity\Product;
@@ -72,17 +70,16 @@ Provide the target class name as the second argument:
     $productInput->sku = 'WM-1024';
 
     $mapper = new ObjectMapper();
-    // Creates a new Product instance and maps properties from $productInput
+    // creates a new Product instance and maps properties from $productInput
     $product = $mapper->map($productInput, Product::class);
 
     // $product is now an instance of Product
     // with $product->name = 'Wireless Mouse' and $product->sku = 'WM-1024'
 
-**Mapping to an Existing Object:**
-
-Provide an existing object instance as the second argument to update it:
+Mapping to an Existing Object
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-::
+Provide an existing object instance as the second argument to update it::
 
     use App\Dto\ProductUpdateInput;
     use App\Entity\Product;
@@ -94,16 +91,16 @@ Provide an existing object instance as the second argument to update it:
     $updateInput->price = 99.99;
 
     $mapper = new ObjectMapper();
-    // Updates the existing $product instance
+    // updates the existing $product instance
     $mapper->map($updateInput, $product);
 
     // $product->price is now 99.99
 
-**Mapping from ``stdClass``:**
+Mapping from ``stdClass``
+~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The source object can also be an instance of ``stdClass``:
-
-::
+The source object can also be an instance of ``stdClass``. This can be
+useful when working with decoded JSON data or loosely typed input::
 
     use App\Entity\Product;
     use Symfony\Component\ObjectMapper\ObjectMapper;
@@ -120,14 +117,13 @@ The source object can also be an instance of ``stdClass``:
 Configuring Mapping with Attributes
 -----------------------------------
 
-The ObjectMapper uses PHP attributes to configure the mapping process. The
-primary attribute is :class:`Symfony\\Component\\ObjectMapper\\Attribute\\Map`.
-
-**Defining the Default Target Class:**
+ObjectMapper uses PHP attributes to configure how properties are mapped.
+The primary attribute is :class:`Symfony\\Component\\ObjectMapper\\Attribute\\Map`.
 
-Apply ``#[Map]`` to the source class to define its default mapping target:
+Defining the Default Target Class
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-::
+Apply ``#[Map]`` to the source class to define its default mapping target::
 
     // src/Dto/ProductInput.php
     namespace App\Dto;
@@ -142,21 +138,22 @@ Apply ``#[Map]`` to the source class to define its default mapping target:
         public string $sku = '';
     }
 
-    // Now you can call map() without the second argument if ProductInput is the source:
+    // now you can call map() without the second argument if ProductInput is the source:
     $mapper = new ObjectMapper();
     $product = $mapper->map($productInput); // Maps to Product automatically
 
-**Configuring Property Mapping:**
+Configuring Property Mapping
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Apply ``#[Map]`` to properties to customize their mapping behavior.
+You can apply the ``#[Map]`` attribute to properties to customize their mapping behavior:
 
-* ``target``: Specifies the name of the property in the target object.
+* ``target``: Specifies the name of the property in the target object;
 * ``source``: Specifies the name of the property in the source object (useful
-    when mapping is defined on the target, see below).
-* ``if``: Defines a condition for mapping the property.
+    when mapping is defined on the target, see below);
+* ``if``: Defines a condition for mapping the property;
 * ``transform``: Applies a transformation to the value before mapping.
 
-::
+This is how it looks in practice::
 
     // src/Dto/OrderInput.php
     namespace App\Dto;
@@ -167,30 +164,29 @@ Apply ``#[Map]`` to properties to customize their mapping behavior.
     #[Map(target: Order::class)]
     class OrderInput
     {
-        // Map 'customerEmail' from source to 'email' in target
+        // map 'customerEmail' from source to 'email' in target
         #[Map(target: 'email')]
         public string $customerEmail = '';
 
-        // Do not map this property at all
+        // do not map this property at all
         #[Map(if: false)]
         public string $internalNotes = '';
 
-        // Only map 'discountCode' if it's a non-empty string
-        #[Map(if: 'strlen')] // Uses the built-in strlen function as a condition
+        // only map 'discountCode' if it's a non-empty string
+        // (uses PHP's strlen() function as a condition)
+        #[Map(if: 'strlen')]
         public ?string $discountCode = null;
     }
 
-By default, if a property exists in the source but not in the target, it's
-ignored. If a property exists in both and has no ``#[Map]`` attribute, it's
-mapped directly if the names match.
+By default, if a property exists in the source but not in the target, it is
+ignored. If a property exists in both and no ``#[Map]`` is defined, the mapper
+assumes a direct mapping when names match.
 
-**Conditional Mapping with Services:**
+Conditional Mapping with Services
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 For complex conditions, you can use a dedicated service implementing
-:class:`Symfony\\Component\\ObjectMapper\\ConditionCallableInterface`. The service
-name (its class name by default) is passed to the ``if`` parameter:
-
-::
+:class:`Symfony\\Component\\ObjectMapper\\ConditionCallableInterface`::
 
     // src/ObjectMapper/IsShippableCondition.php
     namespace App\ObjectMapper;
@@ -206,12 +202,12 @@ name (its class name by default) is passed to the ``if`` parameter:
     {
         public function __invoke(mixed $value, object $source, ?object $target): bool
         {
-            // Example: Only map shipping address if order total is above 50
+            // example: Only map shipping address if order total is above 50
             return $source->total > 50;
         }
     }
 
-::
+Then, pass the service name (its class name by default) to the ``if`` parameter::
 
     // src/Dto/OrderInput.php
     namespace App\Dto;
@@ -233,17 +229,17 @@ For this to work, ``IsShippableCondition`` must be registered as a service.
 
 .. _object_mapper-conditional-property-target:
 
-**Conditional Property Mapping based on Target:**
+Conditional Property Mapping based on Target
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-When a source class can be mapped to multiple target classes, you might want
-to map a specific property only when mapping to a particular target. You can
-achieve this using the :class:`Symfony\\Component\\ObjectMapper\\Condition\\TargetClass`
-condition within the ``if`` parameter on a property's ``#[Map]`` attribute.
+When a source class maps to multiple targets, you may want to include or exclude
+certain properties depending on which target is being used. Use the
+:class:`Symfony\\Component\\ObjectMapper\\Condition\\TargetClass` condition within
+the ``if`` parameter of a property's ``#[Map]`` attribute to achieve this.
 
-This is useful for creating different representations (e.g., public vs. admin)
-from the same source object, offering an alternative to serialization groups.
-
-::
+This pattern is useful for building multiple representations (e.g., public vs. admin)
+from a given source object, and can be used as an alternative to
+:ref:`serialization groups <serializer-groups-attribute>`::
 
     // src/Entity/User.php
     namespace App\Entity;
@@ -253,16 +249,16 @@ from the same source object, offering an alternative to serialization groups.
     use Symfony\Component\ObjectMapper\Attribute\Map;
     use Symfony\Component\ObjectMapper\Condition\TargetClass;
 
-    // This User entity can be mapped to two different DTOs
+    // this User entity can be mapped to two different DTOs
     #[Map(target: PublicUserProfile::class)]
     #[Map(target: AdminUserProfile::class)]
     class User
     {
-        // Map 'lastLoginIp' to 'ipAddress' ONLY when the target is AdminUserProfile
+        // map 'lastLoginIp' to 'ipAddress' ONLY when the target is AdminUserProfile
         #[Map(target: 'ipAddress', if: new TargetClass(AdminUserProfile::class))]
         public ?string $lastLoginIp = '192.168.1.100';
 
-        // Map 'registrationDate' to 'memberSince' for both targets
+        // map 'registrationDate' to 'memberSince' for both targets
         #[Map(target: 'memberSince')]
         public \DateTimeImmutable $registrationDate;
 
@@ -273,24 +269,26 @@ from the same source object, offering an alternative to serialization groups.
 
     // src/Dto/PublicUserProfile.php
     namespace App\Dto;
-    class PublicUserProfile {
+    class PublicUserProfile
+    {
         public \DateTimeImmutable $memberSince;
-        // No $ipAddress property here
+        // no $ipAddress property here
     }
 
     // src/Dto/AdminUserProfile.php
     namespace App\Dto;
-    class AdminUserProfile {
+    class AdminUserProfile
+    {
         public \DateTimeImmutable $memberSince;
-        public ?string $ipAddress = null; // Mapped from lastLoginIp
+        public ?string $ipAddress = null; // mapped from lastLoginIp
     }
 
-    // Usage:
+    // usage:
     $user = new User();
     $mapper = new ObjectMapper();
 
     $publicProfile = $mapper->map($user, PublicUserProfile::class);
-    // No IP address available
+    // no IP address available
 
     $adminProfile = $mapper->map($user, AdminUserProfile::class);
     // $adminProfile->ipAddress = '192.168.1.100'
@@ -298,14 +296,28 @@ from the same source object, offering an alternative to serialization groups.
 Transforming Values
 -------------------
 
-Use the ``transform`` option within ``#[Map]`` to modify a value before it's
-assigned to the target property. The value can be a callable (like a built-in
-PHP function name, a static method, or an anonymous function) or a service
-implementing :class:`Symfony\\Component\\ObjectMapper\\TransformCallableInterface`.
+Use the ``transform`` option within ``#[Map]`` to change a value before it is
+assigned to the target. This can be a callable (e.g., a built-in PHP function,
+static method, or anonymous function) or a service implementing
+:class:`Symfony\\Component\\ObjectMapper\\TransformCallableInterface`.
 
-**Using Callables:**
+Using Callables
+~~~~~~~~~~~~~~~
 
-::
+Consider the following static utility method::
+
+    // src/Util/PriceFormatter.php
+    namespace App\Util;
+
+    class PriceFormatter
+    {
+        public static function format(float $value, object $source): string
+        {
+            return number_format($value, 2, '.', '');
+        }
+    }
+
+You can use that method to format a property when mapping it::
 
     // src/Dto/ProductInput.php
     namespace App\Dto;
@@ -317,31 +329,20 @@ implementing :class:`Symfony\\Component\\ObjectMapper\\TransformCallableInterfac
     #[Map(target: Product::class)]
     class ProductInput
     {
-        // Use a static method from another class for formatting
+        // use a static method from another class for formatting
         #[Map(target: 'displayPrice', transform: [PriceFormatter::class, 'format'])]
         public float $price = 0.0;
 
-        // Can also use simple built-ins
+        // can also use built-in PHP functions
         #[Map(transform: 'intval')]
         public string $stockLevel = '100';
     }
 
-::
-
-    // src/Util/PriceFormatter.php
-    namespace App\Util;
-    class PriceFormatter {
-        public static function format(float $value, object $source): string {
-            return number_format($value, 2, '.', '');
-        }
-    }
-
-**Using Transformer Services:**
+Using Transformer Services
+~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Similar to conditions, complex transformations can be encapsulated in services
-implementing :class:`Symfony\\Component\\ObjectMapper\\TransformCallableInterface`.
-
-::
+implementing :class:`Symfony\\Component\\ObjectMapper\\TransformCallableInterface`::
 
     // src/ObjectMapper/FullNameTransformer.php
     namespace App\ObjectMapper;
@@ -361,7 +362,7 @@ implementing :class:`Symfony\\Component\\ObjectMapper\\TransformCallableInterfac
         }
     }
 
-::
+Then, use this service to format the mapped property::
 
     // src/Dto/UserInput.php
     namespace App\Dto;
@@ -373,24 +374,22 @@ implementing :class:`Symfony\\Component\\ObjectMapper\\TransformCallableInterfac
     #[Map(target: User::class)]
     class UserInput
     {
-        // This property's value will be generated by the transformer
+        // this property's value will be generated by the transformer
         #[Map(target: 'fullName', transform: FullNameTransformer::class)]
         public string $firstName = '';
 
         public string $lastName = '';
     }
 
-**Class-Level Transformation:**
+Class-Level Transformation
+~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-You can apply a ``transform`` callable at the class level. This callable is
-executed *after* the target object is initially created (if the target is a
-class name we use ``newInstanceWithoutConstructor``) but *before* properties
-are mapped. Its responsibility is often to return a correctly initialized
-instance, potentially replacing the one created by the mapper.
-The returned value *must* be an object of the target type or else an
-exception will be thrown.
-
-::
+You can define a transformation at the class level using the ``transform``
+parameter on the ``#[Map]`` attribute. This callable runs *after* the target
+object is created (if the target is a class name, ``newInstanceWithoutConstructor``
+is used), but *before* any properties are mapped. It must return a correctly
+initialized instance of the target class (replacing the one created by the mapper
+if needed)::
 
     // src/Dto/LegacyUserData.php
     namespace App\Dto;
@@ -398,7 +397,7 @@ exception will be thrown.
     use App\Entity\User;
     use Symfony\Component\ObjectMapper\Attribute\Map;
 
-    // Use a static factory method on the target User class for instantiation
+    // use a static factory method on the target User class for instantiation
     #[Map(target: User::class, transform: [User::class, 'createFromLegacy'])]
     class LegacyUserData
     {
@@ -406,15 +405,17 @@ exception will be thrown.
         public string $name = '';
     }
 
-::
+And the related target object must define the ``createFromLegacy()`` method::
 
     // src/Entity/User.php
     namespace App\Entity;
-    class User {
+    class User
+    {
         public string $name = '';
         private int $legacyId = 0;
 
-        private function __construct() {} // Private constructor
+        // uses a private constructor to avoid direct instantiation
+        private function __construct() {}
 
         public static function createFromLegacy(mixed $value, object $source): self
         {
@@ -422,7 +423,8 @@ exception will be thrown.
             // $source is the LegacyUserData object
             $user = new self();
             $user->legacyId = $source->userId;
-            // Property mapping will happen *after* this method returns $user
+
+            // property mapping will happen *after* this method returns $user
             return $user;
         }
     }
@@ -433,9 +435,7 @@ Mapping Multiple Targets
 A source class can be configured to map to multiple different target classes.
 Apply the ``#[Map]`` attribute multiple times at the class level, typically
 using the ``if`` condition to determine which target is appropriate based on the
-source object's state or other logic.
-
-::
+source object's state or other logic::
 
     // src/Dto/EventInput.php
     namespace App\Dto;
@@ -456,146 +456,155 @@ source object's state or other logic.
          */
         public static function isOnline(?mixed $value, object $source): bool
         {
-            return $source->type === 'online';
+            return 'online' === $source->type;
         }
 
         public static function isPhysical(?mixed $value, object $source): bool
         {
-            return $source->type === 'physical';
+            return 'physical' === $source->type;
         }
     }
 
-    // src/Entity/OnlineEvent.php / PhysicalEvent.php ...
+    // consider that the src/Entity/OnlineEvent.php and PhysicalEvent.php
+    // files exist and define the needed classes
 
-    // Usage:
+    // usage:
     $eventInput = new EventInput();
     $eventInput->type = 'physical';
     $mapper = new ObjectMapper();
-    $event = $mapper->map($eventInput); // Automatically maps to PhysicalEvent
+    $event = $mapper->map($eventInput); // automatically maps to PhysicalEvent
 
 Mapping Based on Target Properties (Source Mapping)
 ---------------------------------------------------
 
-Sometimes, it's more convenient to define the mapping on the *target* class,
-specifying where its properties should come from in the *source* class. This is
-done using the ``source`` parameter within the ``#[Map]`` attribute on the target's
-properties.
+Sometimes, it's more convenient to define how a target object should retrieve
+its values from a source, especially when working with external data formats.
+This is done using the ``source`` parameter in the ``#[Map]`` attribute on the
+target class's properties.
 
 Note that if both the ``source`` and the ``target`` classes define the ``#[Map]``
 attribute, the ``source`` takes precedence.
 
-::
+Consider the following class that stores the data obtained form an external API
+that uses snake_case property names::
 
-    // src/Api/Payload.php - Represents data from an external API
+    // src/Api/Payload.php
     namespace App\Api;
+
     class Payload
     {
-        public string $product_name = ''; // Source property name uses snake_case
+        public string $product_name = '';
         public float $price_amount = 0.0;
     }
 
-::
+In your application, classes use camelCase for property names, so you can map
+them as follows::
 
-    // src/Entity/Product.php - Our application's entity
+    // src/Entity/Product.php
     namespace App\Entity;
 
     use App\Api\Payload;
     use Symfony\Component\ObjectMapper\Attribute\Map;
 
-    // Define that Product can be mapped *from* Payload
+    // define that Product can be mapped from Payload
     #[Map(source: Payload::class)]
     class Product
     {
-        // Define where 'name' should get its value from in the Payload source
+        // define where 'name' should get its value from in the Payload source
         #[Map(source: 'product_name')]
-        public string $name = ''; // Target property uses camelCase
+        public string $name = '';
 
-        // Define where 'price' should get its value from
+        // define where 'price' should get its value from
         #[Map(source: 'price_amount')]
         public float $price = 0.0;
     }
 
-    // Usage:
+Using it in practice::
+
     $payload = new Payload();
     $payload->product_name = 'Super Widget';
     $payload->price_amount = 123.45;
 
     $mapper = new ObjectMapper();
-    // Map *from* the payload *to* the Product class
+    // map from the payload to the Product class
     $product = $mapper->map($payload, Product::class);
 
     // $product->name = 'Super Widget'
     // $product->price = 123.45
 
-When using ``source`` mapping, the ``ObjectMapper`` detects this configuration if
-the source object itself doesn't have ``#[Map]`` attributes pointing outwards. It
-then reads the ``#[Map(source: ...)]`` attributes from the target class instead.
+When using source-based mapping, the ``ObjectMapper`` will automatically use the
+target's ``#[Map(source: ...)]`` attributes if no mapping is defined on the
+source class.
 
 Handling Recursion
 ------------------
 
-The ObjectMapper automatically handles recursive relationships. If an object graph
-contains cycles (e.g., a ``User`` has a ``manager`` which is another ``User``,
-who might manage the first user), the mapper will reuse the already mapped target
-instances to avoid infinite loops.
-
-::
+The ObjectMapper automatically detects and handles recursive relationships between
+objects (e.g., a ``User`` has a ``manager`` which is another ``User``, who might
+manage the first user). When it encounters previously mapped objects in the graph,
+it reuses the corresponding target instances to prevent infinite loops::
 
     // src/Entity/User.php
     namespace App\Entity;
+
     use App\Dto\UserDto;
     use Symfony\Component\ObjectMapper\Attribute\Map;
 
     #[Map(target: UserDto::class)]
-    class User {
+    class User
+    {
         public string $name = '';
         public ?User $manager = null;
     }
 
-::
+The target DTO object defines the ``User`` class as its source and the
+ObjectMapper component detects the cyclic reference::
 
     // src/Dto/UserDto.php
     namespace App\Dto;
+
     use Symfony\Component\ObjectMapper\Attribute\Map;
 
-    #[Map(source: \App\Entity\User::class)] // Can also define mapping here
-    class UserDto {
+    #[Map(source: \App\Entity\User::class)] // can also define mapping here
+    class UserDto
+    {
         public string $name = '';
         public ?UserDto $manager = null;
     }
 
-    // Usage:
+Using it in practice::
+
     $manager = new User();
     $manager->name = 'Alice';
     $employee = new User();
     $employee->name = 'Bob';
     $employee->manager = $manager;
-    // Manager's manager is the employee:
+    // manager's manager is the employee:
     $manager->manager = $employee;
 
     $mapper = new ObjectMapper();
     $employeeDto = $mapper->map($employee, UserDto::class);
 
-    // Recursion is handled correctly:
+    // recursion is handled correctly:
     // $employeeDto->name === 'Bob'
     // $employeeDto->manager->name === 'Alice'
     // $employeeDto->manager->manager === $employeeDto
 
-Custom Mapping Logic (MapStruct-like Approach)
-----------------------------------------------
+.. _objectmapper-custom-mapping-logic:
+
+Custom Mapping Logic
+--------------------
 
 For very complex mapping scenarios or if you prefer separating mapping rules from
 your DTOs/Entities, you can implement a custom mapping strategy using the
 :class:`Symfony\\Component\\ObjectMapper\\Metadata\\ObjectMapperMetadataFactoryInterface`.
-This allows defining mapping rules within dedicated "mapper" services, similar
+This allows defining mapping rules within dedicated mapper services, similar
 to the approach used by libraries like MapStruct in the Java ecosystem.
 
 First, create your custom metadata factory. The following example reads mapping
-rules defined via ``#[Map]`` attributes on a dedicated mapper *service* class,
+rules defined via ``#[Map]`` attributes on a dedicated mapper service class,
 specifically on its ``map`` method for property mappings and on the class itself
-for the source-to-target relationship:
-
-::
+for the source-to-target relationship::
 
     namespace App\ObjectMapper\Metadata;
 
@@ -631,18 +640,18 @@ for the source-to-target relationship:
             $mapConfigs = [];
             $sourceIdentifier = $property ?? $object::class;
 
-            // Read attributes from the map method (for property mapping) or the class (for class mapping)
+            // read attributes from the map method (for property mapping) or the class (for class mapping)
             $attributesSource = $property ? $refl->getMethod('map') : $refl;
             foreach ($attributesSource->getAttributes(Map::class, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
                 $map = $attribute->newInstance();
 
-                // Check if the attribute's source matches the current property or source class
+                // check if the attribute's source matches the current property or source class
                 if ($map->source === $sourceIdentifier) {
                     $mapConfigs[] = new Mapping($map->target, $map->source, $map->if, $map->transform);
                 }
             }
 
-            // If it's a property lookup and no specific mapping was found, map to the same property
+            // if it's a property lookup and no specific mapping was found, map to the same property
             if ($property && empty($mapConfigs)) {
                 $mapConfigs[] = new Mapping(target: $property, source: $property);
             }
@@ -651,13 +660,10 @@ for the source-to-target relationship:
         }
     }
 
-Next, define your mapper service class. This class implements
-``ObjectMapperInterface`` but typically delegates the actual mapping back to a
-standard ``ObjectMapper`` instance configured with the custom metadata factory.
-Mapping rules are defined using ``#[Map]`` attributes on this class and its
-``map`` method:
-
-::
+Next, define your mapper service class. This class implements ``ObjectMapperInterface``
+but typically delegates the actual mapping back to a standard ``ObjectMapper``
+instance configured with the custom metadata factory. Mapping rules are defined
+using ``#[Map]`` attributes on this class and its ``map`` method::
 
     namespace App\ObjectMapper;
 
@@ -668,62 +674,65 @@ Mapping rules are defined using ``#[Map]`` attributes on this class and its
     use Symfony\Component\ObjectMapper\ObjectMapper;
     use Symfony\Component\ObjectMapper\ObjectMapperInterface;
 
-    // Define the source-to-target mapping at the class level
+    // define the source-to-target mapping at the class level
     #[Map(source: LegacyUser::class, target: UserDto::class)]
     class LegacyUserMapper implements ObjectMapperInterface
     {
         private readonly ObjectMapperInterface $objectMapper;
 
-        // Inject the standard ObjectMapper or necessary dependencies
+        // inject the standard ObjectMapper or necessary dependencies
         public function __construct(?ObjectMapperInterface $objectMapper = null)
         {
-            // Create an ObjectMapper instance configured with *this* mapper's rules
+            // create an ObjectMapper instance configured with *this* mapper's rules
             $metadataFactory = new MapStructMapperMetadataFactory(self::class);
             $this->objectMapper = $objectMapper ?? new ObjectMapper($metadataFactory);
         }
 
-        // Define property-specific mapping rules on the map method
+        // define property-specific mapping rules on the map method
         #[Map(source: 'fullName', target: 'name')] // Map LegacyUser::fullName to UserDto::name
         #[Map(source: 'creationTimestamp', target: 'registeredAt', transform: [\DateTimeImmutable::class, 'createFromFormat'])]
         #[Map(source: 'status', if: false)] // Ignore the 'status' property from LegacyUser
         public function map(object $source, object|string|null $target = null): object
         {
-            // Delegate the actual mapping to the configured ObjectMapper
+            // delegate the actual mapping to the configured ObjectMapper
             return $this->objectMapper->map($source, $target);
         }
     }
 
-Finally, use your custom mapper service:
-
-::
+Finally, use your custom mapper service::
 
     use App\Dto\LegacyUser;
     use App\ObjectMapper\LegacyUserMapper;
 
     $legacyUser = new LegacyUser();
     $legacyUser->fullName = 'Jane Doe';
-    $legacyUser->status = 'active'; // This will be ignored
+    $legacyUser->status = 'active'; // this will be ignored
 
-    // Instantiate your custom mapper service
+    // instantiate your custom mapper service
     $mapperService = new LegacyUserMapper();
 
-    // Use the map method of your service
+    // use the map method of your service
     $userDto = $mapperService->map($legacyUser); // Target (UserDto) is inferred from #[Map] on LegacyUserMapper
 
-This approach keeps mapping logic centralized within dedicated services, which
-can be beneficial for complex applications or when adhering to specific architectural
-patterns.
+This approach keeps mapping logic centralized within dedicated services, which can
+be beneficial for complex applications or when adhering to specific architectural patterns.
 
 Advanced Configuration
 ----------------------
 
-The ``ObjectMapper`` constructor accepts optional arguments for further customization:
-
-* ``ObjectMapperMetadataFactoryInterface $metadataFactory``: Allows providing a custom metadata factory, as shown in the MapStruct example. Defaults to :class:`Symfony\\Component\\ObjectMapper\\Metadata\\ReflectionObjectMapperMetadataFactory`, which reads ``#[Map]`` attributes directly from source/target classes.
-* ``?PropertyAccessorInterface $propertyAccessor``: An instance of the PropertyAccess component to customize how properties are read from the source and written to the target. Useful for accessing private properties or using getters/setters.
-* ``?ContainerInterface $transformCallableLocator``: A PSR-11 container (service locator) used to resolve service IDs provided in the ``transform`` option of ``#[Map]``.
-* ``?ContainerInterface $conditionCallableLocator``: A PSR-11 container used to resolve service IDs provided in the ``if`` option of ``#[Map]``.
-
-When using the ``ObjectMapperInterface`` service provided by the Symfony framework,
-these dependencies (like the property accessor and service locators for callables)
-are typically configured automatically via the service container.
+The ``ObjectMapper`` constructor accepts optional arguments for advanced usage:
+
+* ``ObjectMapperMetadataFactoryInterface $metadataFactory``: Allows custom metadata
+  factories, such as the one shown in :ref:`the MapStruct-like example <objectmapper-custom-mapping-logic>`.
+  The default is :class:`Symfony\\Component\\ObjectMapper\\Metadata\\ReflectionObjectMapperMetadataFactory`,
+  which uses ``#[Map]`` attributes from source and target classes.
+* ``?PropertyAccessorInterface $propertyAccessor``: Lets you customize how
+  properties are read and written to the target object, useful for accessing
+  private properties or using getters/setters.
+* ``?ContainerInterface $transformCallableLocator``: A PSR-11 container (service locator)
+  that resolves service IDs referenced by the ``transform`` option in ``#[Map]``.
+* ``?ContainerInterface $conditionCallableLocator``: A PSR-11 container for resolving
+  service IDs used in ``if`` conditions within ``#[Map]``.
+
+These dependencies are automatically configured when you use the
+``ObjectMapperInterface`` service provided by Symfony.

From d371dcb3e3d94d13c4ace077bfaf359894aa3c1c Mon Sep 17 00:00:00 2001
From: Antoine Lamirault <lamiraultantoine@gmail.com>
Date: Thu, 1 May 2025 14:24:54 +0200
Subject: [PATCH 654/747] Use phpunit 11 in Create Framework tutorial

---
 create_framework/unit_testing.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/create_framework/unit_testing.rst b/create_framework/unit_testing.rst
index f935a024b20..9c179cd3152 100644
--- a/create_framework/unit_testing.rst
+++ b/create_framework/unit_testing.rst
@@ -12,7 +12,7 @@ using `PHPUnit`_. At first, install PHPUnit as a development dependency:
 
 .. code-block:: terminal
 
-    $ composer require --dev phpunit/phpunit:^10.0
+    $ composer require --dev phpunit/phpunit:^11.0
 
 Then, create a PHPUnit configuration file in ``example.com/phpunit.xml.dist``:
 
@@ -21,7 +21,7 @@ Then, create a PHPUnit configuration file in ``example.com/phpunit.xml.dist``:
     <?xml version="1.0" encoding="UTF-8"?>
     <phpunit
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd"
+        xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.0/phpunit.xsd"
         backupGlobals="false"
         colors="true"
         bootstrap="vendor/autoload.php"
@@ -212,6 +212,6 @@ Symfony code.
 Now that we are confident (again) about the code we have written, we can
 safely think about the next batch of features we want to add to our framework.
 
-.. _`PHPUnit`: https://docs.phpunit.de/en/10.0/
-.. _`test doubles`: https://docs.phpunit.de/en/10.0/test-doubles.html
+.. _`PHPUnit`: https://docs.phpunit.de/en/11.0/
+.. _`test doubles`: https://docs.phpunit.de/en/11.0/test-doubles.html
 .. _`XDebug`: https://xdebug.org/

From 280cd5a506ee06549d8e072f806208a56dd30d73 Mon Sep 17 00:00:00 2001
From: Nicolas Grekas <nicolas.grekas@gmail.com>
Date: Sun, 11 May 2025 18:15:53 +0200
Subject: [PATCH 655/747] [Cache] Mention Valkey is Redis

---
 components/cache/adapters/redis_adapter.rst | 6 ++++++
 configuration/secrets.rst                   | 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/components/cache/adapters/redis_adapter.rst b/components/cache/adapters/redis_adapter.rst
index 3362f4cc2db..e029b51b0d3 100644
--- a/components/cache/adapters/redis_adapter.rst
+++ b/components/cache/adapters/redis_adapter.rst
@@ -21,6 +21,11 @@ to utilize a cluster of servers to provide redundancy and/or fail-over is also a
     adapter. Additionally, this adapter requires a compatible extension or library that implements
     ``\Redis``, ``\RedisArray``, ``RedisCluster``, ``\Relay\Relay`` or ``\Predis``.
 
+.. note::
+
+   This adapter also works with `Valkey`_ servers and as of Symfony 7.3, you can use the ``valkey[s]:`` schemes
+   instead of the ``redis[s]:`` ones in your DSNs.
+
 This adapter expects a `Redis`_, `RedisArray`_, `RedisCluster`_, `Relay`_ or `Predis`_ instance to be
 passed as the first parameter. A namespace and default cache lifetime can optionally be passed
 as the second and third parameters::
@@ -348,6 +353,7 @@ Supports key rotation, ensuring secure decryption with both old and new keys::
 
 .. _`Data Source Name (DSN)`: https://en.wikipedia.org/wiki/Data_source_name
 .. _`Redis server`: https://redis.io/
+.. _`Valkey`: https://valkey.io/
 .. _`Redis`: https://github.com/phpredis/phpredis
 .. _`RedisArray`: https://github.com/phpredis/phpredis/blob/develop/arrays.md
 .. _`RedisCluster`: https://github.com/phpredis/phpredis/blob/develop/cluster.md
diff --git a/configuration/secrets.rst b/configuration/secrets.rst
index f717456a22c..285b89d521e 100644
--- a/configuration/secrets.rst
+++ b/configuration/secrets.rst
@@ -311,7 +311,7 @@ The secrets system is enabled by default and some of its behavior can be configu
                 xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
                     http://symfony.com/schema/dic/framework https://symfony.com/schema/dic/framework/framework-1.0.xsd"
             >
-                <framework:config secret="%env(APP_SECRET)%">
+                <framework:config>
                     <framework:secrets
                         vault_directory="%kernel.project_dir%/config/secrets/%kernel.environment%"
                         local_dotenv_file="%kernel.project_dir%/.env.%kernel.environment%.local"

From 8c5f22b3e69142381f9d84dfb4adafab46eb8c1e Mon Sep 17 00:00:00 2001
From: Quentin Devos <4972091+Okhoshi@users.noreply.github.com>
Date: Sat, 10 May 2025 13:25:03 +0200
Subject: [PATCH 656/747] [TwigBundle] Describe the new behaviour of twig.cache
 config

Signed-off-by: Quentin Devos <4972091+Okhoshi@users.noreply.github.com>
---
 reference/configuration/twig.rst | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst
index 3c4dc1b30ac..13d0463970a 100644
--- a/reference/configuration/twig.rst
+++ b/reference/configuration/twig.rst
@@ -71,7 +71,7 @@ application harder to maintain.
 cache
 ~~~~~
 
-**type**: ``string`` | ``false`` **default**: ``%kernel.cache_dir%/twig``
+**type**: ``string`` | ``boolean`` **default**: ``true``
 
 Before using the Twig templates to render some contents, they are compiled into
 regular PHP code. Compilation is a costly process, so the result is cached in
@@ -82,6 +82,16 @@ is not recommended; not even in the ``dev`` environment, because the
 ``auto_reload`` option ensures that cached templates which have changed get
 compiled again.
 
+Specify the path where the cache should be stored. If set to ``true``, the cache
+defaults to ``%kernel.cache_dir%/twig``. However, if the ``auto_reload`` option is
+disabled and ``%kernel.build_dir%`` is different from ``%kernel.cache_dir%``,
+the cache will instead be stored in ``%kernel.build_dir%/twig``.
+
+.. versionadded:: 7.3
+
+    Support for ``true`` value was added in Symfony 7.3, and it became the default
+    value for this option instead of ``%kernel.cache_dir%/twig``.
+
 charset
 ~~~~~~~
 

From 0ba6600aca5f21dddaeb8d3c68188de10c770b12 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 12 May 2025 08:06:02 +0200
Subject: [PATCH 657/747] Minor tweak

---
 components/cache/adapters/redis_adapter.rst | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/components/cache/adapters/redis_adapter.rst b/components/cache/adapters/redis_adapter.rst
index e029b51b0d3..0d099bf66e8 100644
--- a/components/cache/adapters/redis_adapter.rst
+++ b/components/cache/adapters/redis_adapter.rst
@@ -8,7 +8,8 @@ Redis Cache Adapter
     :ref:`Symfony Cache configuration <cache-configuration-with-frameworkbundle>`
     article if you are using it in a Symfony application.
 
-This adapter stores the values in-memory using one (or more) `Redis server`_ instances.
+This adapter stores the values in-memory using one (or more) `Redis server`_
+of `Valkey`_ server instances.
 
 Unlike the :doc:`APCu adapter </components/cache/adapters/apcu_adapter>`, and similarly to the
 :doc:`Memcached adapter </components/cache/adapters/memcached_adapter>`, it is not limited to the current server's
@@ -21,11 +22,6 @@ to utilize a cluster of servers to provide redundancy and/or fail-over is also a
     adapter. Additionally, this adapter requires a compatible extension or library that implements
     ``\Redis``, ``\RedisArray``, ``RedisCluster``, ``\Relay\Relay`` or ``\Predis``.
 
-.. note::
-
-   This adapter also works with `Valkey`_ servers and as of Symfony 7.3, you can use the ``valkey[s]:`` schemes
-   instead of the ``redis[s]:`` ones in your DSNs.
-
 This adapter expects a `Redis`_, `RedisArray`_, `RedisCluster`_, `Relay`_ or `Predis`_ instance to be
 passed as the first parameter. A namespace and default cache lifetime can optionally be passed
 as the second and third parameters::
@@ -66,6 +62,11 @@ helper method allows creating and configuring the Redis client class instance us
         'redis://localhost'
     );
 
+.. versionadded:: 7.3
+
+    Starting in Symfony 7.3, when using Valkey servers you can use the
+    ``valkey[s]:`` scheme instead of the ``redis[s]:`` one in your DSNs.
+
 The DSN can specify either an IP/host (and an optional port) or a socket path, as well as a
 password and a database index. To enable TLS for connections, the scheme ``redis`` must be
 replaced by ``rediss`` (the second ``s`` means "secure").

From fcf4ecbd598f66748ee16bd108ee013a444ea285 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 12 May 2025 08:30:12 +0200
Subject: [PATCH 658/747] Minor reword

---
 reference/configuration/twig.rst | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst
index 13d0463970a..360309fef8f 100644
--- a/reference/configuration/twig.rst
+++ b/reference/configuration/twig.rst
@@ -77,20 +77,21 @@ Before using the Twig templates to render some contents, they are compiled into
 regular PHP code. Compilation is a costly process, so the result is cached in
 the directory defined by this configuration option.
 
-Set this option to ``false`` to disable Twig template compilation. However, this
-is not recommended; not even in the ``dev`` environment, because the
-``auto_reload`` option ensures that cached templates which have changed get
-compiled again.
+You can either specify a custom path where the cache should be stored (as a
+string) or use ``true`` to let Symfony decide the default path. When set to
+``true``, the cache is stored in ``%kernel.cache_dir%/twig`` by default. However,
+if ``auto_reload`` is disabled and ``%kernel.build_dir%`` differs from
+``%kernel.cache_dir%``, the cache will be stored in ``%kernel.build_dir%/twig`` instead.
 
-Specify the path where the cache should be stored. If set to ``true``, the cache
-defaults to ``%kernel.cache_dir%/twig``. However, if the ``auto_reload`` option is
-disabled and ``%kernel.build_dir%`` is different from ``%kernel.cache_dir%``,
-the cache will instead be stored in ``%kernel.build_dir%/twig``.
+Set this option to ``false`` to disable Twig template compilation. However, this
+is not recommended, not even in the ``dev`` environment, because the ``auto_reload``
+option ensures that cached templates which have changed get compiled again.
 
 .. versionadded:: 7.3
 
-    Support for ``true`` value was added in Symfony 7.3, and it became the default
-    value for this option instead of ``%kernel.cache_dir%/twig``.
+    Support for using ``true`` as a value was introduced in Symfony 7.3. It also
+    became the default value for this option, replacing the explicit path
+    ``%kernel.cache_dir%/twig``.
 
 charset
 ~~~~~~~

From ca203cfe621fac81b29b3a7f256f14bfbaaa29b7 Mon Sep 17 00:00:00 2001
From: Nicolas Grekas <nicolas.grekas@gmail.com>
Date: Mon, 12 May 2025 10:39:13 +0200
Subject: [PATCH 659/747] [Security] Tell about erasing credentials when the
 user is stored in the session

---
 reference/configuration/security.rst |  5 ++++
 security.rst                         | 35 +++++++++++++++++++++-------
 2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst
index 6f4fcd8db33..72970a845d8 100644
--- a/reference/configuration/security.rst
+++ b/reference/configuration/security.rst
@@ -53,6 +53,11 @@ erase_credentials
 If ``true``, the ``eraseCredentials()`` method of the user object is called
 after authentication.
 
+.. deprecated:: 7.3
+
+   Since Symfony 7.3, ``eraseCredentials()`` methods are deprecated and are
+   not called if they have the ``#[\Deprecated]`` attribute.
+
 hide_user_not_found
 -------------------
 
diff --git a/security.rst b/security.rst
index 847f90a1e2c..36b56e115ee 100644
--- a/security.rst
+++ b/security.rst
@@ -193,14 +193,7 @@ from the `MakerBundle`_:
             return $this;
         }
 
-        /**
-         * @see UserInterface
-         */
-        public function eraseCredentials(): void
-        {
-            // If you store any temporary, sensitive data on the user, clear it here
-            // $this->plainPassword = null;
-        }
+        // [...]
     }
 
 .. tip::
@@ -2786,7 +2779,31 @@ object) are "compared" to see if they are "equal". By default, the core
 your user will be logged out. This is a security measure to make sure that malicious
 users can be de-authenticated if core user data changes.
 
-However, in some cases, this process can cause unexpected authentication problems.
+Note that storing the (plain or hashed) password in the session storage can be seen
+as a security risk. In order to address this risk, the ``__serialize()`` magic method
+can be implemented on the user class to filter out the password before storing the
+serialized user object in the session.
+Two strategies are supported while serializing:
+
+#. Removing the password entirely. In this case, ``getPassword()`` will return ``null``
+   after unserialization and Symfony will refresh the user without checking the
+   password. Use this strategy if you store plaintext passwords (not recommended.)
+#. Hashing the password using the ``crc32c`` algorithm. In this case Symfony will
+   compare the password of the refreshed user after crc32c-hashing it. This is a good
+   strategy if you use hashed passwords since it allows invalidating concurrent
+   sessions when a password changes without storing the password hash in the session.
+
+   Here is an example of how to implement this, assuming the password is found in a
+   private property named ``password``::
+
+       public function __serialize(): array
+       {
+           $data = (array) $this;
+           $data["\0".self::class."\0password"] = hash('crc32c', $this->password);
+
+           return $data;
+       }
+
 If you're having problems authenticating, it could be that you *are* authenticating
 successfully, but you immediately lose authentication after the first redirect.
 

From 33bd9a8976e2b25fa909a16695a0dcb5ab9cefd4 Mon Sep 17 00:00:00 2001
From: Nicolas Grekas <nicolas.grekas@gmail.com>
Date: Mon, 12 May 2025 12:14:44 +0200
Subject: [PATCH 660/747] Update doc about lazy objects

---
 components/var_exporter.rst         | 42 +++++++++++++++++++++++++++--
 service_container/lazy_services.rst |  8 ------
 2 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/components/var_exporter.rst b/components/var_exporter.rst
index fc6b34868db..dc83763d579 100644
--- a/components/var_exporter.rst
+++ b/components/var_exporter.rst
@@ -177,8 +177,34 @@ populated by using the special ``"\0"`` property name to define their internal v
         "\0" => [$inputArray],
     ]);
 
-Creating Lazy Objects
----------------------
+Creating Lazy Objects on PHP ≥ 8.4
+----------------------------------
+
+Since version 8.4, PHP provides support for lazy objects via the reflection API.
+This native API works with concrete classes. It doesn't with abstracts nor with
+internal ones.
+
+This components provides helpers to generate lazy objects using the decorator
+pattern, which works with abstract or internal classes and with interfaces::
+
+    $proxyCode = ProxyHelper::generateLazyProxy(new \ReflectionClass(SomeInterface::class));
+    // $proxyCode should be dumped into a file in production envs
+    eval('class ProxyDecorator'.$proxyCode);
+
+    $proxy = ProxyDecorator::createLazyProxy(initializer: function (): SomeInterface {
+        // [...] Use whatever heavy logic you need here
+        // to compute the $dependencies of the proxied class
+        $instance = new SomeHeavyClass(...$dependencies);
+        // [...] Call setters, etc. if needed
+
+        return $instance;
+    });
+
+Use this mechanism only when native lazy objects cannot be leveraged
+(or you'll get a deprecation notice.)
+
+Creating Lazy Objects on PHP < 8.3
+----------------------------------
 
 Lazy-objects are objects instantiated empty and populated on-demand. This is
 particularly useful when you have for example properties in your classes that
@@ -193,6 +219,12 @@ you implement such mechanism easily in your classes.
 LazyGhostTrait
 ~~~~~~~~~~~~~~
 
+.. deprecated:: 7.3
+
+   ``LazyGhostTrait`` is deprecated since Symfony 7.3; use PHP 8.4's native lazy
+   objects instead (note that using the trait with PHP < 8.4 triggers no deprecation
+   to help with the transition.)
+
 Ghost objects are empty objects, which see their properties populated the first
 time any method is called. Thanks to :class:`Symfony\\Component\\VarExporter\\LazyGhostTrait`,
 the implementation of the lazy mechanism is eased. The ``MyLazyObject::populateHash()``
@@ -273,6 +305,12 @@ of :ref:`Virtual Proxies <var-exporter_virtual-proxies>`.
 LazyProxyTrait
 ~~~~~~~~~~~~~~
 
+.. deprecated:: 7.3
+
+   ``LazyProxyTrait`` is deprecated since Symfony 7.3; use PHP 8.4's native lazy
+   objects instead (note that using the trait with PHP < 8.4 triggers no deprecation
+   to help with the transition.)
+
 The purpose of virtual proxies in the same one as
 :ref:`ghost objects <var-exporter_ghost-objects>`, but their internal behavior is
 totally different. Where ghost objects requires to extend a base class, virtual
diff --git a/service_container/lazy_services.rst b/service_container/lazy_services.rst
index 23d76a4cfbf..abb3c2cca7f 100644
--- a/service_container/lazy_services.rst
+++ b/service_container/lazy_services.rst
@@ -26,9 +26,6 @@ until you interact with the proxy in some way.
     Lazy services do not support `final`_ or ``readonly`` classes, but you can use
     `Interface Proxifying`_ to work around this limitation.
 
-    In PHP versions prior to 8.0 lazy services do not support parameters with
-    default values for built-in PHP classes (e.g. ``PDO``).
-
 .. _lazy-services_configuration:
 
 Configuration
@@ -78,11 +75,6 @@ same signature of the class representing the service should be injected. A lazy
 itself when being accessed for the first time). The same happens when calling
 ``Container::get()`` directly.
 
-To check if your lazy service works you can check the interface of the received object::
-
-    dump(class_implements($service));
-    // the output should include "Symfony\Component\VarExporter\LazyObjectInterface"
-
 You can also configure your service's laziness thanks to the
 :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Autoconfigure` attribute.
 For example, to define your service as lazy use the following::

From 8459dff249cf3e83ad19957a9bf9664e0e7411e2 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 12 May 2025 15:42:25 +0200
Subject: [PATCH 661/747] Minor tweaks

---
 reference/configuration/security.rst | 15 +++++++++++-
 security.rst                         | 36 +++++++++++++++-------------
 2 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst
index 72970a845d8..c8609c20c9c 100644
--- a/reference/configuration/security.rst
+++ b/reference/configuration/security.rst
@@ -51,7 +51,20 @@ erase_credentials
 **type**: ``boolean`` **default**: ``true``
 
 If ``true``, the ``eraseCredentials()`` method of the user object is called
-after authentication.
+after authentication::
+
+    use Symfony\Component\Security\Core\User\UserInterface;
+
+    class User implements UserInterface
+    {
+        // ...
+
+        public function eraseCredentials(): void
+        {
+            // If you store any temporary, sensitive data on the user, clear it here
+            // $this->plainPassword = null;
+        }
+    }
 
 .. deprecated:: 7.3
 
diff --git a/security.rst b/security.rst
index 36b56e115ee..82f26957f02 100644
--- a/security.rst
+++ b/security.rst
@@ -2779,22 +2779,21 @@ object) are "compared" to see if they are "equal". By default, the core
 your user will be logged out. This is a security measure to make sure that malicious
 users can be de-authenticated if core user data changes.
 
-Note that storing the (plain or hashed) password in the session storage can be seen
-as a security risk. In order to address this risk, the ``__serialize()`` magic method
-can be implemented on the user class to filter out the password before storing the
-serialized user object in the session.
-Two strategies are supported while serializing:
-
-#. Removing the password entirely. In this case, ``getPassword()`` will return ``null``
-   after unserialization and Symfony will refresh the user without checking the
-   password. Use this strategy if you store plaintext passwords (not recommended.)
-#. Hashing the password using the ``crc32c`` algorithm. In this case Symfony will
-   compare the password of the refreshed user after crc32c-hashing it. This is a good
-   strategy if you use hashed passwords since it allows invalidating concurrent
-   sessions when a password changes without storing the password hash in the session.
-
-   Here is an example of how to implement this, assuming the password is found in a
-   private property named ``password``::
+Storing the (plain or hashed) password in the session can be a security risk.
+To mitigate this, implement the ``__serialize()`` magic method in your user class
+to exclude or transform the password before storing the serialized user object
+in the session.
+
+Two strategies are supported:
+
+#. Remove the password completely. After unserialization, ``getPassword()`` returns
+   ``null`` and Symfony refreshes the user without checking the password. Use this
+   only if you store plaintext passwords (not recommended).
+#. Hash the password using the ``crc32c`` algorithm. Symfony will hash the password
+   of the refreshed user and compare it to the session value. This approach avoids
+   storing the real hash and lets you invalidate sessions on password change.
+
+   Example (assuming the password is stored in a private property called ``password``)::
 
        public function __serialize(): array
        {
@@ -2804,6 +2803,11 @@ Two strategies are supported while serializing:
            return $data;
        }
 
+.. versionadded:: 7.3
+
+    Support for hashing passwords with ``crc32c`` in session serialization was
+    introduced in Symfony 7.3.
+
 If you're having problems authenticating, it could be that you *are* authenticating
 successfully, but you immediately lose authentication after the first redirect.
 

From e899545ee62e4954ef4d35d06f46a42e5b659df5 Mon Sep 17 00:00:00 2001
From: Nicolas Grekas <nicolas.grekas@gmail.com>
Date: Mon, 12 May 2025 16:18:59 +0200
Subject: [PATCH 662/747] [Cache] Tell about namespace-based invalidation

---
 components/cache.rst | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/components/cache.rst b/components/cache.rst
index 4873fb7abc7..e2bce1cf812 100644
--- a/components/cache.rst
+++ b/components/cache.rst
@@ -84,6 +84,33 @@ generate and return the value::
     Use cache tags to delete more than one key at the time. Read more at
     :doc:`/components/cache/cache_invalidation`.
 
+Creating Sub-Namespaces
+-----------------------
+
+All cache adapters provided by the component implement the
+:method:`Symfony\\Contracts\\Cache\\NamespacedPoolInterface::withSubNamespace` method
+from the :class:`Symfony\\Contracts\\Cache\\NamespacedPoolInterface`.
+
+.. versionadded:: 7.3
+
+   Support for ``NamespacedPoolInterface`` was added in Symfony 7.3.
+
+This method allows namespacing cached items by transparently prefixing their keys::
+
+    $subCache = $cache->withSubNamespace('foo');
+
+    $subCache->get('my_cache_key', function (ItemInterface $item): string {
+        $item->expiresAfter(3600);
+
+        return '...';
+    });
+
+In this example, cache item keyed ``my_cache_key`` will be transparently stored within
+the cache pool under a logical namespace called ``foo``.
+
+Sub-namespacing allows implementing namespace-based cache invalidation, where the name
+of a namespace is computed by hashing some context info.
+
 .. _cache_stampede-prevention:
 
 Stampede Prevention

From daad10ca8112f82376deb6cfe5e3e6790de0a2df Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 13 May 2025 09:12:55 +0200
Subject: [PATCH 663/747] Tweaks

---
 components/cache.rst | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/components/cache.rst b/components/cache.rst
index e2bce1cf812..3c124c7d85e 100644
--- a/components/cache.rst
+++ b/components/cache.rst
@@ -87,14 +87,13 @@ generate and return the value::
 Creating Sub-Namespaces
 -----------------------
 
-All cache adapters provided by the component implement the
-:method:`Symfony\\Contracts\\Cache\\NamespacedPoolInterface::withSubNamespace` method
-from the :class:`Symfony\\Contracts\\Cache\\NamespacedPoolInterface`.
-
 .. versionadded:: 7.3
 
-   Support for ``NamespacedPoolInterface`` was added in Symfony 7.3.
+   Cache sub-namespaces were introduced in Symfony 7.3.
 
+All cache adapters provided by the component implement the
+:class:`Symfony\\Contracts\\Cache\\NamespacedPoolInterface` to provide the
+:method:`Symfony\\Contracts\\Cache\\NamespacedPoolInterface::withSubNamespace` method.
 This method allows namespacing cached items by transparently prefixing their keys::
 
     $subCache = $cache->withSubNamespace('foo');
@@ -105,11 +104,17 @@ This method allows namespacing cached items by transparently prefixing their key
         return '...';
     });
 
-In this example, cache item keyed ``my_cache_key`` will be transparently stored within
-the cache pool under a logical namespace called ``foo``.
+In this example, the cache item will use the ``my_cache_key`` key, but it will be
+stored internally under the ``foo`` namespace. This is handled transparently for
+you, so you **don't** need to manually prefix keys like ``foo.my_cache_key``.
+
+This is useful when using namespace-based cache invalidation to isolate or
+invalidate a subset of cached data based on some context. Typical examples
+include namespacing by user ID, locale, or entity ID and hash::
 
-Sub-namespacing allows implementing namespace-based cache invalidation, where the name
-of a namespace is computed by hashing some context info.
+    $userCache = $cache->withSubNamespace((string) $userId);
+    $localeCache = $cache->withSubNamespace($request->getLocale());
+    $productCache = $cache->withSubNamespace($productId.'_'.$productChecksum);
 
 .. _cache_stampede-prevention:
 

From 849acdebaae132db61e2ede92be3f2c21718bdfc Mon Sep 17 00:00:00 2001
From: Nicolas Grekas <nicolas.grekas@gmail.com>
Date: Mon, 12 May 2025 17:08:31 +0200
Subject: [PATCH 664/747] [DI] Tell about #[AutowireInline]

---
 service_container/autowiring.rst | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/service_container/autowiring.rst b/service_container/autowiring.rst
index 32688fd4921..d76622db281 100644
--- a/service_container/autowiring.rst
+++ b/service_container/autowiring.rst
@@ -862,6 +862,38 @@ typed properties:
             }
         }
 
+Autowiring Anonymous Services Inline
+------------------------------------
+
+.. versionadded:: 7.1
+
+   The ``#[AutowireInline]`` attribute was added in Symfony 7.1.
+
+Similar to how one can define anonymous services inline using configuration files,
+the :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireInline`
+attribute allows declaring anonymous services inline next to their corresponding
+arguments::
+
+    public function __construct(
+        #[AutowireInline(
+            factory: [ScopingHttpClient::class, 'forBaseUri'],
+            arguments: [
+                '$baseUri' => 'https://api.example.com',
+                '$defaultOptions' => [
+                    'auth_bearer' => '%env(EXAMPLE_TOKEN)%',
+                ],
+            ]
+        )]
+        private HttpClientInterface $client,
+    ) {
+    }
+
+As you might have already figured out, this declaration instructs Symfony to inject an
+object created by calling the ``ScopingHttpClient::forBaseUri()`` factory with the
+configured base URI and default options.
+
+Of course, this is just an example and this attribute can be used to construct any kind of objects.
+
 Autowiring Controller Action Methods
 ------------------------------------
 

From 7253f1bef0f23c788e83b5d7b36eace90073386f Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 14 May 2025 09:30:26 +0200
Subject: [PATCH 665/747] Minor tweaks

---
 service_container/autowiring.rst | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/service_container/autowiring.rst b/service_container/autowiring.rst
index d76622db281..ea1bf1b12ff 100644
--- a/service_container/autowiring.rst
+++ b/service_container/autowiring.rst
@@ -869,10 +869,10 @@ Autowiring Anonymous Services Inline
 
    The ``#[AutowireInline]`` attribute was added in Symfony 7.1.
 
-Similar to how one can define anonymous services inline using configuration files,
+Similar to how anonymous services can be defined inline in configuration files,
 the :class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireInline`
-attribute allows declaring anonymous services inline next to their corresponding
-arguments::
+attribute allows you to declare anonymous services inline, directly next to their
+corresponding arguments::
 
     public function __construct(
         #[AutowireInline(
@@ -888,11 +888,13 @@ arguments::
     ) {
     }
 
-As you might have already figured out, this declaration instructs Symfony to inject an
-object created by calling the ``ScopingHttpClient::forBaseUri()`` factory with the
-configured base URI and default options.
+This example tells Symfony to inject an object created by calling the
+``ScopingHttpClient::forBaseUri()`` factory with the specified base URI and
+default options. This is just one example: you can use the ``#[AutowireInline]``
+attribute to define any kind of anonymous service.
 
-Of course, this is just an example and this attribute can be used to construct any kind of objects.
+While this approach is convenient for simple service definitions, consider moving
+complex or heavily configured services to a configuration file to ease maintenance.
 
 Autowiring Controller Action Methods
 ------------------------------------

From 5de8d6ba7f95c16a7cfea69e540f363927e8f7f9 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 14 May 2025 17:20:51 +0200
Subject: [PATCH 666/747] Minor tweaks

---
 components/var_exporter.rst | 56 ++++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/components/var_exporter.rst b/components/var_exporter.rst
index dc83763d579..c7ec9cd90d0 100644
--- a/components/var_exporter.rst
+++ b/components/var_exporter.rst
@@ -177,53 +177,53 @@ populated by using the special ``"\0"`` property name to define their internal v
         "\0" => [$inputArray],
     ]);
 
-Creating Lazy Objects on PHP ≥ 8.4
-----------------------------------
+Creating Lazy Objects
+---------------------
 
-Since version 8.4, PHP provides support for lazy objects via the reflection API.
-This native API works with concrete classes. It doesn't with abstracts nor with
-internal ones.
+Lazy objects are objects instantiated empty and populated on demand. This is
+particularly useful when, for example, a class has properties that require
+heavy computation to determine their values. In such cases, you may want to
+trigger the computation only when the property is actually accessed. This way,
+the expensive processing is avoided entirely if the property is never used.
 
-This components provides helpers to generate lazy objects using the decorator
-pattern, which works with abstract or internal classes and with interfaces::
+Since version 8.4, PHP provides support for lazy objects via the reflection API.
+This native API works with concrete classes, but not with abstract or internal ones.
+This component provides helpers to generate lazy objects using the decorator
+pattern, which also works with abstract classes, internal classes, and interfaces::
 
     $proxyCode = ProxyHelper::generateLazyProxy(new \ReflectionClass(SomeInterface::class));
-    // $proxyCode should be dumped into a file in production envs
+    // $proxyCode should be dumped into a file in production environments
     eval('class ProxyDecorator'.$proxyCode);
 
     $proxy = ProxyDecorator::createLazyProxy(initializer: function (): SomeInterface {
-        // [...] Use whatever heavy logic you need here
+        // use whatever heavy logic you need here
         // to compute the $dependencies of the proxied class
         $instance = new SomeHeavyClass(...$dependencies);
-        // [...] Call setters, etc. if needed
+        // call setters, etc. if needed
 
         return $instance;
     });
 
 Use this mechanism only when native lazy objects cannot be leveraged
-(or you'll get a deprecation notice.)
+(otherwise you'll get a deprecation notice).
 
-Creating Lazy Objects on PHP < 8.3
-----------------------------------
+Legacy Creation of Lazy Objects
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Lazy-objects are objects instantiated empty and populated on-demand. This is
-particularly useful when you have for example properties in your classes that
-requires some heavy computation to determine their value. In this case, you
-may want to trigger the property's value processing only when you actually need
-its value. Thanks to this, the heavy computation won't be done if you never use
-this property. The VarExporter component is bundled with two traits helping
-you implement such mechanism easily in your classes.
+When using a PHP version earlier than 8.4, native lazy objects are not available.
+In these cases, the VarExporter component provides two traits that help you
+implement lazy-loading mechanisms in your classes.
 
 .. _var-exporter_ghost-objects:
 
 LazyGhostTrait
-~~~~~~~~~~~~~~
+..............
 
 .. deprecated:: 7.3
 
-   ``LazyGhostTrait`` is deprecated since Symfony 7.3; use PHP 8.4's native lazy
-   objects instead (note that using the trait with PHP < 8.4 triggers no deprecation
-   to help with the transition.)
+    ``LazyGhostTrait`` is deprecated since Symfony 7.3. Use PHP 8.4's native lazy
+    objects instead. Note that using the trait with PHP versions earlier than 8.4
+    does not trigger a deprecation, to ease the transition.
 
 Ghost objects are empty objects, which see their properties populated the first
 time any method is called. Thanks to :class:`Symfony\\Component\\VarExporter\\LazyGhostTrait`,
@@ -303,13 +303,13 @@ of :ref:`Virtual Proxies <var-exporter_virtual-proxies>`.
 .. _var-exporter_virtual-proxies:
 
 LazyProxyTrait
-~~~~~~~~~~~~~~
+..............
 
 .. deprecated:: 7.3
 
-   ``LazyProxyTrait`` is deprecated since Symfony 7.3; use PHP 8.4's native lazy
-   objects instead (note that using the trait with PHP < 8.4 triggers no deprecation
-   to help with the transition.)
+    ``LazyProxyTrait`` is deprecated since Symfony 7.3. Use PHP 8.4's native lazy
+    objects instead. Note that using the trait with PHP versions earlier than 8.4
+    does not trigger a deprecation, to ease the transition.
 
 The purpose of virtual proxies in the same one as
 :ref:`ghost objects <var-exporter_ghost-objects>`, but their internal behavior is

From 5ad20ab99619534ee744c0efc2498fe878536bc7 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 15 May 2025 15:27:25 +0200
Subject: [PATCH 667/747] [Cache] Improve the docs about cache namespaces

---
 cache.rst            |  2 ++
 components/cache.rst | 59 +++++++++++++++++++++++++++++++++-----------
 2 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/cache.rst b/cache.rst
index 83bb5b4cedc..35f1404d42a 100644
--- a/cache.rst
+++ b/cache.rst
@@ -539,6 +539,8 @@ Symfony stores the item automatically in all the missing pools.
             ;
         };
 
+.. _cache-using-cache-tags:
+
 Using Cache Tags
 ----------------
 
diff --git a/components/cache.rst b/components/cache.rst
index 3c124c7d85e..b476b23e313 100644
--- a/components/cache.rst
+++ b/components/cache.rst
@@ -91,30 +91,61 @@ Creating Sub-Namespaces
 
    Cache sub-namespaces were introduced in Symfony 7.3.
 
-All cache adapters provided by the component implement the
-:class:`Symfony\\Contracts\\Cache\\NamespacedPoolInterface` to provide the
-:method:`Symfony\\Contracts\\Cache\\NamespacedPoolInterface::withSubNamespace` method.
-This method allows namespacing cached items by transparently prefixing their keys::
+Sometimes you need to create context-dependent variations of data that should be
+cached. For example, the data used to render a dashboard page may be expensive
+to generate and unique per user, so you can't cache the same data for everyone.
 
-    $subCache = $cache->withSubNamespace('foo');
+In such cases, Symfony allows you to create different cache contexts using
+namespaces. A cache namespace is an arbitrary string that identifies a set of
+related cache items. All cache adapters provided by the component implement the
+:class:`Symfony\\Contracts\\Cache\\NamespacedPoolInterface`, which provides the
+:method:`Symfony\\Contracts\\Cache\\NamespacedPoolInterface::withSubNamespace`
+method.
 
-    $subCache->get('my_cache_key', function (ItemInterface $item): string {
+This method allows you to namespace cached items by transparently prefixing their keys::
+
+    $userCache = $cache->withSubNamespace(sprintf('user-%d', $user->getId()));
+
+    $userCache->get('dashboard_data', function (ItemInterface $item): string {
         $item->expiresAfter(3600);
 
         return '...';
     });
 
-In this example, the cache item will use the ``my_cache_key`` key, but it will be
-stored internally under the ``foo`` namespace. This is handled transparently for
-you, so you **don't** need to manually prefix keys like ``foo.my_cache_key``.
+In this example, the cache item uses the ``dashboard_data`` key, but it will be
+stored internally under a namespace based on the current user ID. This is handled
+automatically, so you **don’t** need to manually prefix keys like ``user-27.dashboard_data``.
 
-This is useful when using namespace-based cache invalidation to isolate or
-invalidate a subset of cached data based on some context. Typical examples
-include namespacing by user ID, locale, or entity ID and hash::
+There are no guidelines or restrictions on how to define cache namespaces.
+You can make them as granular or as generic as your application requires:
 
-    $userCache = $cache->withSubNamespace((string) $userId);
     $localeCache = $cache->withSubNamespace($request->getLocale());
-    $productCache = $cache->withSubNamespace($productId.'_'.$productChecksum);
+
+    $flagCache = $cache->withSubNamespace(
+        $featureToggle->isEnabled('new_checkout') ? 'checkout-v2' : 'checkout-v1'
+    );
+
+    $channel = $request->attributes->get('_route')?->startsWith('api_') ? 'api' : 'web';
+    $channelCache = $cache->withSubNamespace($channel);
+
+.. tip::
+
+    You can even combine cache namespaces with :ref:`cache tags <cache-using-cache-tags>`
+    for more advanced needs.
+
+There is no built-in way to invalidate caches by namespace. Instead, the recommended
+approach is to change the namespace itself. For this reason, it's common to include
+static or dynamic versioning data in the cache namespace::
+
+    // for simple applications, an incrementing static version number may be enough
+    $userCache = $cache->withSubNamespace(sprintf('v1-user-%d', $user->getId()));
+
+    // other applications may use dynamic versioning based on the date (e.g. monthly)
+    $userCache = $cache->withSubNamespace(sprintf('%s-user-%d', date('Ym'), $user->getId()));
+
+    // or even invalidate the cache when the user data changes
+    $checksum = hash('xxh128', $user->getUpdatedAt()->format(DATE_ATOM));
+    $userCache = $cache->withSubNamespace(sprintf('user-%d-%s', $user->getId(), $checksum));
 
 .. _cache_stampede-prevention:
 

From e0fcd1c3bd46b7bca6bd4a1eeb7e3c687d0d3cf6 Mon Sep 17 00:00:00 2001
From: Romain Monteil <monteil.romain@gmail.com>
Date: Thu, 15 May 2025 15:20:18 +0200
Subject: [PATCH 668/747] [Workflow] Document custom workflow definition
 validator

---
 workflow.rst | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/workflow.rst b/workflow.rst
index 11b4005bb10..544f775cce0 100644
--- a/workflow.rst
+++ b/workflow.rst
@@ -1306,6 +1306,85 @@ In Twig templates, metadata is available via the ``workflow_metadata()`` functio
         </ul>
     </p>
 
+Adding Custom Definition Validators
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sometimes, you may want to add custom logics to validate your workflow definition.
+To do this, you need to implement the
+:class:`Symfony\\Component\\Workflow\\Validator\\DefinitionValidatorInterface`::
+
+    namespace App\Workflow\Validator;
+
+    use Symfony\Component\Workflow\Definition;
+    use Symfony\Component\Workflow\Exception\InvalidDefinitionException;
+    use Symfony\Component\Workflow\Validator\DefinitionValidatorInterface;
+
+    final class BlogPublishingValidator implements DefinitionValidatorInterface
+    {
+        public function validate(Definition $definition, string $name): void
+        {
+            if (!$definition->getMetadataStore()->getMetadata('title')) {
+                throw new InvalidDefinitionException(sprintf('The workflow metadata title is missing in Workflow "%s".', $name));
+            }
+        }
+    }
+
+Once your definition validator is implemented, you can configure your workflow to use
+it:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/workflow.yaml
+        framework:
+            workflows:
+                blog_publishing:
+                    # ... previous configuration
+
+                    definition_validators:
+                        - App\Workflow\Validator\BlogPublishingValidator
+
+    .. code-block:: xml
+
+        <!-- config/packages/workflow.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"
+        >
+            <framework:config>
+                <framework:workflow name="blog_publishing">
+                    <!-- ... previous configuration -->
+                    <framework:definition-validators>App\Workflow\Validator\BlogPublishingValidator</framework:definition-validators>
+                </framework:workflow>
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/workflow.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            $blogPublishing = $framework->workflows()->workflows('blog_publishing');
+            // ... previous configuration
+
+            $blogPublishing->definitionValidators([
+                App\Workflow\Validator\BlogPublishingValidator::class
+            ]);
+
+            // ...
+        };
+
+The ``BlogPublishingValidator`` definition validator will be executed during the container compilation.
+
+.. versionadded:: 7.3
+
+    Support for defining custom workflow definition validators was introduced in Symfony 7.3.
+
 Learn more
 ----------
 

From e228ab6178987867ea65dce15acb8e3de311f5bb Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 16 May 2025 08:09:04 +0200
Subject: [PATCH 669/747] Minor tweaks

---
 components/cache.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/components/cache.rst b/components/cache.rst
index b476b23e313..44c08920a1e 100644
--- a/components/cache.rst
+++ b/components/cache.rst
@@ -114,7 +114,7 @@ This method allows you to namespace cached items by transparently prefixing thei
 
 In this example, the cache item uses the ``dashboard_data`` key, but it will be
 stored internally under a namespace based on the current user ID. This is handled
-automatically, so you **don’t** need to manually prefix keys like ``user-27.dashboard_data``.
+automatically, so you **don't** need to manually prefix keys like ``user-27.dashboard_data``.
 
 There are no guidelines or restrictions on how to define cache namespaces.
 You can make them as granular or as generic as your application requires:
@@ -130,7 +130,7 @@ You can make them as granular or as generic as your application requires:
 
 .. tip::
 
-    You can even combine cache namespaces with :ref:`cache tags <cache-using-cache-tags>`
+    You can combine cache namespaces with :ref:`cache tags <cache-using-cache-tags>`
     for more advanced needs.
 
 There is no built-in way to invalidate caches by namespace. Instead, the recommended

From 4b8a58cfee6cd87fcae7df58f28ccb47a0534830 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 16 May 2025 08:56:43 +0200
Subject: [PATCH 670/747] Fix a minor synmtax issue

---
 components/cache.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/cache.rst b/components/cache.rst
index 44c08920a1e..44ba8b5c151 100644
--- a/components/cache.rst
+++ b/components/cache.rst
@@ -117,7 +117,7 @@ stored internally under a namespace based on the current user ID. This is handle
 automatically, so you **don't** need to manually prefix keys like ``user-27.dashboard_data``.
 
 There are no guidelines or restrictions on how to define cache namespaces.
-You can make them as granular or as generic as your application requires:
+You can make them as granular or as generic as your application requires::
 
     $localeCache = $cache->withSubNamespace($request->getLocale());
 

From 4579583cb6304e707413f0d4d5abaa1454572231 Mon Sep 17 00:00:00 2001
From: Nicolas Grekas <nicolas.grekas@gmail.com>
Date: Tue, 13 May 2025 14:04:30 +0200
Subject: [PATCH 671/747] [Security] Tell about stateless CSRF protection

---
 http_cache/varnish.rst                |   2 +-
 reference/configuration/framework.rst |  59 ++++++++-
 security/csrf.rst                     | 184 ++++++++++++++++++++++++--
 session.rst                           |   2 +-
 4 files changed, 233 insertions(+), 14 deletions(-)

diff --git a/http_cache/varnish.rst b/http_cache/varnish.rst
index a9bb668c100..6fcb7fd766b 100644
--- a/http_cache/varnish.rst
+++ b/http_cache/varnish.rst
@@ -62,7 +62,7 @@ If you know for sure that the backend never uses sessions or basic
 authentication, have Varnish remove the corresponding header from requests to
 prevent clients from bypassing the cache. In practice, you will need sessions
 at least for some parts of the site, e.g. when using forms with
-:doc:`CSRF Protection </security/csrf>`. In this situation, make sure to
+:doc:`stateful CSRF Protection </security/csrf>`. In this situation, make sure to
 :ref:`only start a session when actually needed <session-avoid-start>`
 and clear the session when it is no longer needed. Alternatively, you can look
 into :ref:`caching pages that contain CSRF protected forms <caching-pages-that-contain-csrf-protected-forms>`.
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 599cbb0ba04..8fec2678c8d 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -805,8 +805,6 @@ csrf_protection
 
     For more information about CSRF protection, see :doc:`/security/csrf`.
 
-.. _reference-csrf_protection-enabled:
-
 enabled
 .......
 
@@ -854,6 +852,42 @@ If you're using forms, but want to avoid starting your session (e.g. using
 forms in an API-only website), ``csrf_protection`` will need to be set to
 ``false``.
 
+stateless_token_ids
+...................
+
+**type**: ``array`` **default**: ``[]``
+
+The list of CSRF token ids that will use stateless CSRF protection.
+
+.. versionadded:: 7.2
+
+    This option was added in Symfony 7.2 to aid in configuring stateless CSRF protection.
+
+check_header
+............
+
+**type**: ``integer`` or ``bool`` **default**: ``false``
+
+Whether to check the CSRF token in a header in addition to a cookie when using stateless protection.
+Can be set to ``2`` (the value of the ``CHECK_ONLY_HEADER`` constant on the
+:class:`Symfony\\Component\\Security\\Csrf\\SameOriginCsrfTokenManager` class) to check only the header
+and not the cookie.
+
+.. versionadded:: 7.2
+
+    This option was added in Symfony 7.2 to aid in configuring stateless CSRF protection.
+
+cookie_name
+...........
+
+**type**: ``string`` **default**: ``csrf-token``
+
+The name of the cookie (and header) to use for the double-submit when using stateless protection.
+
+.. versionadded:: 7.2
+
+    This option was added in Symfony 7.2 to aid in configuring stateless CSRF protection.
+
 .. _config-framework-default_locale:
 
 default_locale
@@ -1164,15 +1198,32 @@ settings is configured.
 
     For more details, see :doc:`/forms`.
 
-.. _reference-form-field-name:
+csrf_protection
+...............
 
 field_name
-..........
+''''''''''
 
 **type**: ``string`` **default**: ``_token``
 
 This is the field name that you should give to the CSRF token field of your forms.
 
+field_attr
+''''''''''
+
+**type**: ``array`` **default**: ``['data-controller' => 'csrf-protection']``
+
+This is the HTML attributes that should be added to the CSRF token field of your forms.
+
+token_id
+''''''''
+
+**type**: ``string`` **default**: ``null``
+
+This is the CSRF token id that should be used for validating the CSRF tokens of your forms.
+Note that this setting applies only to autoconfigured form types, which usually means only
+to your own form types and not to form types registered by third-party bundles.
+
 fragments
 ~~~~~~~~~
 
diff --git a/security/csrf.rst b/security/csrf.rst
index 772b503ec39..2e7369d170f 100644
--- a/security/csrf.rst
+++ b/security/csrf.rst
@@ -34,6 +34,10 @@ unique tokens added to forms as hidden fields. The legit server validates them t
 ensure that the request originated from the expected source and not some other
 malicious website.
 
+Anti-CSRF tokens can be managed either in a stateful way: they're put in the
+session and are unique for each user and for each kind of action, or in a
+stateless way: they're generated on the client-side.
+
 Installation
 ------------
 
@@ -85,14 +89,14 @@ for more information):
             ;
         };
 
-The tokens used for CSRF protection are meant to be different for every user and
-they are stored in the session. That's why a session is started automatically as
-soon as you render a form with CSRF protection.
+By default, the tokens used for CSRF protection are stored in the session.
+That's why a session is started automatically as soon as you render a form
+with CSRF protection.
 
 .. _caching-pages-that-contain-csrf-protected-forms:
 
-Moreover, this means that you cannot fully cache pages that include CSRF
-protected forms. As an alternative, you can:
+This leads to many strategies to help with caching pages that include CSRF
+protected forms, among them:
 
 * Embed the form inside an uncached :doc:`ESI fragment </http_cache/esi>` and
   cache the rest of the page contents;
@@ -101,6 +105,9 @@ protected forms. As an alternative, you can:
   load the CSRF token with an uncached AJAX request and replace the form
   field value with it.
 
+The most effective way to cache pages that need CSRF protected forms is to use
+stateless CSRF tokens, see below.
+
 .. _csrf-protection-forms:
 
 CSRF Protection in Symfony Forms
@@ -183,6 +190,7 @@ method of each form::
                 'csrf_field_name' => '_token',
                 // an arbitrary string used to generate the value of the token
                 // using a different string for each form improves its security
+                // when using stateful tokens (which is the default)
                 'csrf_token_id'   => 'task_item',
             ]);
         }
@@ -190,7 +198,7 @@ method of each form::
         // ...
     }
 
-You can also customize the rendering of the CSRF form field creating a custom
+You can also customize the rendering of the CSRF form field by creating a custom
 :doc:`form theme </form/form_themes>` and using ``csrf_token`` as the prefix of
 the field (e.g. define ``{% block csrf_token_widget %} ... {% endblock %}`` to
 customize the entire form field contents).
@@ -221,7 +229,7 @@ generate a CSRF token in the template and store it as a hidden form field:
 .. code-block:: html+twig
 
     <form action="{{ url('admin_post_delete', { id: post.id }) }}" method="post">
-        {# the argument of csrf_token() is an arbitrary string used to generate the token #}
+        {# the argument of csrf_token() is the ID of this token #}
         <input type="hidden" name="token" value="{{ csrf_token('delete-item') }}">
 
         <button type="submit">Delete item</button>
@@ -229,7 +237,7 @@ generate a CSRF token in the template and store it as a hidden form field:
 
 Then, get the value of the CSRF token in the controller action and use the
 :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController::isCsrfTokenValid`
-method to check its validity::
+method to check its validity, passing the same token ID used in the template::
 
     use Symfony\Component\HttpFoundation\Request;
     use Symfony\Component\HttpFoundation\Response;
@@ -302,6 +310,166 @@ targeted parts of the plaintext. To mitigate these attacks, and prevent an
 attacker from guessing the CSRF tokens, a random mask is prepended to the token
 and used to scramble it.
 
+Stateless CSRF Tokens
+---------------------
+
+.. versionadded:: 7.2
+
+    Stateless anti-CSRF protection was introduced in Symfony 7.2.
+
+By default CSRF tokens are stateful, which means they're stored in the session.
+But some token ids can be declared as stateless using the ``stateless_token_ids``
+option:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/csrf.yaml
+        framework:
+            # ...
+            csrf_protection:
+                stateless_token_ids: ['submit', 'authenticate', 'logout']
+
+    .. code-block:: xml
+
+        <!-- config/packages/csrf.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony
+                https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <framework:config>
+                <framework:csrf-protection>
+                    <framework:stateless-token-id>submit</framework:stateless-token-id>
+                    <framework:stateless-token-id>authenticate</framework:stateless-token-id>
+                    <framework:stateless-token-id>logout</framework:stateless-token-id>
+                </framework:csrf-protection>
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/csrf.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            $framework->csrfProtection()
+                ->statelessTokenIds(['submit', 'authenticate', 'logout'])
+            ;
+        };
+
+Stateless CSRF tokens use a CSRF protection that doesn't need the session. This
+means that you can cache the entire page and still have CSRF protection.
+
+When a stateless CSRF token is checked for validity, Symfony verifies the
+``Origin`` and the ``Referer`` headers of the incoming HTTP request.
+
+If either of these headers match the target origin of the application (its domain
+name), the CSRF token is considered valid. This relies on the app being able to
+know its own target origin. Don't miss configuring your reverse proxy if you're
+behind one. See :doc:`/deployment/proxies`.
+
+Using a Default Token ID
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+While stateful CSRF tokens are better seggregated per form or action, stateless
+ones don't need many token identifiers. In the previous example, ``authenticate``
+and ``logout`` are listed because they're the default identifiers used by the
+Symfony Security component. The ``submit`` identifier is then listed so that
+form types defined by the application can use it by default. The following
+configuration - which applies only to form types declared using autofiguration
+(the default way to declare *your* services) - will make your form types use the
+``submit`` token identifier by default:
+
+.. configuration-block::
+
+    .. code-block:: yaml
+
+        # config/packages/csrf.yaml
+        framework:
+            form:
+                csrf_protection:
+                    token_id: 'submit'
+
+    .. code-block:: xml
+
+        <!-- config/packages/csrf.xml -->
+        <?xml version="1.0" encoding="UTF-8" ?>
+        <container xmlns="http://symfony.com/schema/dic/services"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:framework="http://symfony.com/schema/dic/symfony"
+            xsi:schemaLocation="http://symfony.com/schema/dic/services
+                https://symfony.com/schema/dic/services/services-1.0.xsd
+                http://symfony.com/schema/dic/symfony
+                https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
+
+            <framework:config>
+                <framework:form>
+                    <framework:csrf-protection token-id="submit"/>
+                </framework:form>
+            </framework:config>
+        </container>
+
+    .. code-block:: php
+
+        // config/packages/csrf.php
+        use Symfony\Config\FrameworkConfig;
+
+        return static function (FrameworkConfig $framework): void {
+            $framework->form()
+                ->csrfProtection()
+                    ->tokenId('submit')
+            ;
+        };
+
+Forms configured with a token identifier listed in the above ``stateless_token_ids``
+option will use the stateless CSRF protection.
+
+Generating CSRF Token Using Javascript
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In addition to the ``Origin`` and ``Referer`` headers, stateless CSRF protection
+also checks a cookie and a header (named ``csrf-token`` by default, see the
+:ref:`CSRF configuration reference <reference-framework-csrf-protection>`).
+
+These extra checks are part of defense-in-depth strategies provided by the
+stateless CSRF protection. They are optional and they require
+`some JavaScript`_ to be activated. This JavaScript is responsible for generating
+a crypto-safe random token when a form is submitted, then putting the token in
+the hidden CSRF field of the form and submitting it also as a cookie and header.
+On the server-side, the CSRF token is validated by checking the cookie and header
+values. This "double-submit" protection relies on the same-origin policy
+implemented by browsers and is strengthened by regenerating the token at every
+form submission - which prevents cookie fixation issues - and by using
+``samesite=strict`` and ``__Host-`` cookies, which make them domain-bound and
+HTTPS-only.
+
+Note that the default snippet of JavaScript provided by Symfony requires that
+the hidden CSRF form field is either named ``_csrf_token``, or that it has the
+``data-controller="csrf-protection"`` attribute. You can of course take
+inspiration from this snippet to write your own, provided you follow the same
+protocol.
+
+As a last measure, a behavioral check is added on the server-side to ensure that
+the validation method cannot be downgraded: if and only if a session is already
+available, successful "double-submit" is remembered and is then required for
+subsequent requests. This prevents attackers from exploiting potentially reduced
+validation checks once cookie and/or header validation has been confirmed as
+effective (they're optional by default as explained above).
+
+.. note::
+
+    Enforcing successful "double-submit" for every requests is not recommended as
+    as it could lead to a broken user experience. The opportunistic approach
+    described above is preferred because it allows the application to gracefully
+    degrade to ``Origin`` / ``Referer`` checks when JavaScript is not available.
+
 .. _`Cross-site request forgery`: https://en.wikipedia.org/wiki/Cross-site_request_forgery
 .. _`BREACH`: https://en.wikipedia.org/wiki/BREACH
 .. _`CRIME`: https://en.wikipedia.org/wiki/CRIME
+.. _`some JavaScript`: https://github.com/symfony/recipes/blob/main/symfony/stimulus-bundle/2.20/assets/controllers/csrf_protection_controller.js
diff --git a/session.rst b/session.rst
index 0c5348ec9e6..4c14638fc68 100644
--- a/session.rst
+++ b/session.rst
@@ -115,7 +115,7 @@ sessions for anonymous users, you must *completely* avoid accessing the session.
 .. note::
 
     Sessions will also be started when using features that rely on them internally,
-    such as the :ref:`CSRF protection in forms <csrf-protection-forms>`.
+    such as the :ref:`stateful CSRF protection in forms <csrf-protection-forms>`.
 
 .. _flash-messages:
 

From e591c5903958e63eaf1bc7d9b470431b29904f8c Mon Sep 17 00:00:00 2001
From: Nicolas Grekas <nicolas.grekas@gmail.com>
Date: Mon, 12 May 2025 15:16:58 +0200
Subject: [PATCH 672/747] [Routing] Tell about {foo:bar} mapping syntax

---
 doctrine.rst | 31 +++++++++++--------------------
 routing.rst  | 43 ++++++++++++++++++++++++++++++++-----------
 2 files changed, 43 insertions(+), 31 deletions(-)

diff --git a/doctrine.rst b/doctrine.rst
index 171f8a3348a..270c59a08c4 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -680,7 +680,7 @@ will automatically fetch them::
     /**
      * Perform a findOneBy() where the slug property matches {slug}.
      */
-    #[Route('/product/{slug}')]
+    #[Route('/product/{slug:product}')]
     public function showBySlug(Product $product): Response
     {
     }
@@ -694,14 +694,17 @@ Automatic fetching works in these situations:
   *all* of the wildcards in your route that are actually properties
   on your entity (non-properties are ignored).
 
-This behavior is enabled by default on all controllers. If you prefer, you can
-restrict this feature to only work on route wildcards called ``id`` to look for
-entities by primary key. To do so, set the option
-``doctrine.orm.controller_resolver.auto_mapping`` to ``false``.
+The ``{slug:product}`` syntax maps the route parameter named ``slug`` to the
+controller argument named ``$product``. It also hints the resolver to lookup
+by slug when loading the corresponding ``Product`` object from the database.
 
-When ``auto_mapping`` is disabled, you can configure the mapping explicitly for
-any controller argument with the ``MapEntity`` attribute. You can even control
-the ``EntityValueResolver`` behavior by using the `MapEntity options`_ ::
+.. versionadded:: 7.1
+
+    Route parameter mapping was introduced in Symfony 7.1.
+
+You can also configure the mapping explicitly for any controller argument
+with the ``MapEntity`` attribute. You can even control the
+``EntityValueResolver`` behavior by using the `MapEntity options`_ ::
 
     // src/Controller/ProductController.php
     namespace App\Controller;
@@ -812,18 +815,6 @@ control behavior:
         ): Response {
         }
 
-``exclude``
-    Configures the properties that should be used in the ``findOneBy()``
-    method by *excluding* one or more properties so that not *all* are used::
-
-        #[Route('/product/{slug}/{date}')]
-        public function show(
-            #[MapEntity(exclude: ['date'])]
-            Product $product,
-            \DateTime $date
-        ): Response {
-        }
-
 ``stripNull``
     If true, then when ``findOneBy()`` is used, any values that are
     ``null`` will not be used for the query.
diff --git a/routing.rst b/routing.rst
index 24218eaf74c..587a35f269b 100644
--- a/routing.rst
+++ b/routing.rst
@@ -22,8 +22,7 @@ Creating Routes as Attributes
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 PHP attributes allow to define routes next to the code of the
-:doc:`controllers </controller>` associated to those routes. Attributes are
-native in PHP 8 and higher versions, so you can use them right away.
+:doc:`controllers </controller>` associated to those routes.
 
 You need to add a bit of configuration to your project before using them. If your
 project uses :ref:`Symfony Flex <symfony-flex>`, this file is already created for you.
@@ -707,12 +706,6 @@ URL                       Route          Parameters
     matches any uppercase character in any language, ``\p{Greek}`` matches any
     Greek characters, etc.
 
-.. note::
-
-    When using regular expressions in route parameters, you can set the ``utf8``
-    route option to ``true`` to make any ``.`` character match any UTF-8
-    characters instead of just a single byte.
-
 If you prefer, requirements can be inlined in each parameter using the syntax
 ``{parameter_name<requirements>}``. This feature makes configuration more
 concise, but it can decrease route readability when requirements are complex:
@@ -998,7 +991,7 @@ controller action. Instead of ``string $slug``, add ``BlogPost $post``::
     {
         // ...
 
-        #[Route('/blog/{slug}', name: 'blog_show')]
+        #[Route('/blog/{slug:post}', name: 'blog_show')]
         public function show(BlogPost $post): Response
         {
             // $post is the object whose slug matches the routing parameter
@@ -1012,9 +1005,37 @@ this case), the "param converter" makes a database request to find the object
 using the request parameters (``slug`` in this case). If no object is found,
 Symfony generates a 404 response automatically.
 
+The ``{slug:post}`` syntax maps the route parameter named ``slug`` to the controller
+argument named ``$post``. It also hints the "param converter" to lookup by slug
+when loading the corresponding ``BlogPost`` object from the database.
+
+.. versionadded:: 7.1
+
+    Route parameter mapping was introduced in Symfony 7.1.
+
+When more than one entity needs to be derived from route parameters, collisions can happen.
+In the following example, the route tries to define two mappings: one to load an author by
+name, two to load a category by name. But this is not allowed because from the side of the
+route definition, this declares a parameter named "name" twice::
+
+    #[Route('/search-book/{name:author}/{name:category}')]
+
+Such routes should instead be defined using the following syntax::
+
+    #[Route('/search-book/{authorName:author.name}/{categoryName:category.name}')]
+
+This way, the route parameter names are unique (``authorName`` and ``categoryName``) and
+the "param converter" can correctly map them to controller arguments (``$author`` and
+``$category``), loading them both by their name.
+
+.. versionadded:: 7.3
+
+    This more advanced style of route parameter mapping was introduced in Symfony 7.3.
+
+More advanced mappings can be achieved using the ``#[MapEntity]`` attribute.
 Check out the :ref:`Doctrine param conversion documentation <doctrine-entity-value-resolver>`
-to learn about the ``#[MapEntity]`` attribute that can be used to customize the
-database queries used to fetch the object from the route parameter.
+to learn how to customize the database queries used to fetch the object from the route
+parameter.
 
 Backed Enum Parameters
 ~~~~~~~~~~~~~~~~~~~~~~

From e8128a60528c45de2833c9eb1bf692daf963fadf Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@open.de>
Date: Tue, 20 May 2025 08:55:56 +0200
Subject: [PATCH 673/747] remove the Slug constraint

---
 reference/constraints/Slug.rst    | 119 ------------------------------
 reference/constraints/map.rst.inc |   1 -
 2 files changed, 120 deletions(-)
 delete mode 100644 reference/constraints/Slug.rst

diff --git a/reference/constraints/Slug.rst b/reference/constraints/Slug.rst
deleted file mode 100644
index 2eb82cd9c10..00000000000
--- a/reference/constraints/Slug.rst
+++ /dev/null
@@ -1,119 +0,0 @@
-Slug
-====
-
-.. versionadded:: 7.3
-
-    The ``Slug`` constraint was introduced in Symfony 7.3.
-
-Validates that a value is a slug. By default, a slug is a string that matches
-the following regular expression: ``/^[a-z0-9]+(?:-[a-z0-9]+)*$/``.
-
-.. include:: /reference/constraints/_empty-values-are-valid.rst.inc
-
-==========  ===================================================================
-Applies to  :ref:`property or method <validation-property-target>`
-Class       :class:`Symfony\\Component\\Validator\\Constraints\\Slug`
-Validator   :class:`Symfony\\Component\\Validator\\Constraints\\SlugValidator`
-==========  ===================================================================
-
-Basic Usage
------------
-
-The ``Slug`` constraint can be applied to a property or a getter method:
-
-.. configuration-block::
-
-    .. code-block:: php-attributes
-
-        // src/Entity/Author.php
-        namespace App\Entity;
-
-        use Symfony\Component\Validator\Constraints as Assert;
-
-        class Author
-        {
-            #[Assert\Slug]
-            protected string $slug;
-        }
-
-    .. code-block:: yaml
-
-        # config/validator/validation.yaml
-        App\Entity\Author:
-            properties:
-                slug:
-                    - Slug: ~
-
-    .. code-block:: xml
-
-        <!-- config/validator/validation.xml -->
-        <?xml version="1.0" encoding="UTF-8" ?>
-        <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
-
-            <class name="App\Entity\Author">
-                <property name="slug">
-                    <constraint name="Slug"/>
-                </property>
-            </class>
-        </constraint-mapping>
-
-    .. code-block:: php
-
-        // src/Entity/Author.php
-        namespace App\Entity;
-
-        use Symfony\Component\Validator\Constraints as Assert;
-        use Symfony\Component\Validator\Mapping\ClassMetadata;
-
-        class Author
-        {
-            // ...
-
-            public static function loadValidatorMetadata(ClassMetadata $metadata): void
-            {
-                $metadata->addPropertyConstraint('slug', new Assert\Slug());
-            }
-        }
-
-Examples of valid values:
-
-* foobar
-* foo-bar
-* foo123
-* foo-123bar
-
-Uppercase characters would result in an violation of this constraint.
-
-Options
--------
-
-``regex``
-~~~~~~~~~
-
-**type**: ``string`` default: ``/^[a-z0-9]+(?:-[a-z0-9]+)*$/``
-
-This option allows you to modify the regular expression pattern that the input
-will be matched against via the :phpfunction:`preg_match` PHP function.
-
-If you need to use it, you might also want to take a look at the :doc:`Regex constraint <Regex>`.
-
-``message``
-~~~~~~~~~~~
-
-**type**: ``string`` **default**: ``This value is not a valid slug``
-
-This is the message that will be shown if this validator fails.
-
-You can use the following parameters in this message:
-
-=================  ==============================================================
-Parameter          Description
-=================  ==============================================================
-``{{ value }}``    The current (invalid) value
-=================  ==============================================================
-
-.. include:: /reference/constraints/_groups-option.rst.inc
-
-.. include:: /reference/constraints/_payload-option.rst.inc
diff --git a/reference/constraints/map.rst.inc b/reference/constraints/map.rst.inc
index c2396ae3af7..06680e42207 100644
--- a/reference/constraints/map.rst.inc
+++ b/reference/constraints/map.rst.inc
@@ -33,7 +33,6 @@ String Constraints
 * :doc:`NotCompromisedPassword </reference/constraints/NotCompromisedPassword>`
 * :doc:`PasswordStrength </reference/constraints/PasswordStrength>`
 * :doc:`Regex </reference/constraints/Regex>`
-* :doc:`Slug </reference/constraints/Slug>`
 * :doc:`Twig </reference/constraints/Twig>`
 * :doc:`Ulid </reference/constraints/Ulid>`
 * :doc:`Url </reference/constraints/Url>`

From 88a7eb25c60453e95dd9cf782238f2855b9e4738 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 20 May 2025 09:17:27 +0200
Subject: [PATCH 674/747] Minor tweaks

---
 doctrine.rst |  8 ++++----
 routing.rst  | 23 ++---------------------
 2 files changed, 6 insertions(+), 25 deletions(-)

diff --git a/doctrine.rst b/doctrine.rst
index 270c59a08c4..a55ff8fe600 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -695,16 +695,16 @@ Automatic fetching works in these situations:
   on your entity (non-properties are ignored).
 
 The ``{slug:product}`` syntax maps the route parameter named ``slug`` to the
-controller argument named ``$product``. It also hints the resolver to lookup
-by slug when loading the corresponding ``Product`` object from the database.
+controller argument named ``$product``. It also hints the resolver to look up
+the corresponding ``Product`` object from the database using the slug.
 
 .. versionadded:: 7.1
 
     Route parameter mapping was introduced in Symfony 7.1.
 
 You can also configure the mapping explicitly for any controller argument
-with the ``MapEntity`` attribute. You can even control the
-``EntityValueResolver`` behavior by using the `MapEntity options`_ ::
+using the ``MapEntity`` attribute. You can even control the behavior of the
+``EntityValueResolver`` by using the `MapEntity options`_ ::
 
     // src/Controller/ProductController.php
     namespace App\Controller;
diff --git a/routing.rst b/routing.rst
index 587a35f269b..810c753ec3a 100644
--- a/routing.rst
+++ b/routing.rst
@@ -1006,32 +1006,13 @@ using the request parameters (``slug`` in this case). If no object is found,
 Symfony generates a 404 response automatically.
 
 The ``{slug:post}`` syntax maps the route parameter named ``slug`` to the controller
-argument named ``$post``. It also hints the "param converter" to lookup by slug
-when loading the corresponding ``BlogPost`` object from the database.
+argument named ``$post``. It also hints the "param converter" to look up the
+corresponding ``BlogPost`` object from the database using the slug.
 
 .. versionadded:: 7.1
 
     Route parameter mapping was introduced in Symfony 7.1.
 
-When more than one entity needs to be derived from route parameters, collisions can happen.
-In the following example, the route tries to define two mappings: one to load an author by
-name, two to load a category by name. But this is not allowed because from the side of the
-route definition, this declares a parameter named "name" twice::
-
-    #[Route('/search-book/{name:author}/{name:category}')]
-
-Such routes should instead be defined using the following syntax::
-
-    #[Route('/search-book/{authorName:author.name}/{categoryName:category.name}')]
-
-This way, the route parameter names are unique (``authorName`` and ``categoryName``) and
-the "param converter" can correctly map them to controller arguments (``$author`` and
-``$category``), loading them both by their name.
-
-.. versionadded:: 7.3
-
-    This more advanced style of route parameter mapping was introduced in Symfony 7.3.
-
 More advanced mappings can be achieved using the ``#[MapEntity]`` attribute.
 Check out the :ref:`Doctrine param conversion documentation <doctrine-entity-value-resolver>`
 to learn how to customize the database queries used to fetch the object from the route

From d71927f9e9eb83a697416e76f5928af85bbbe38a Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 20 May 2025 09:21:53 +0200
Subject: [PATCH 675/747] [Routing] Readd the 7.3 docs about advance param
 mapping

---
 routing.rst | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/routing.rst b/routing.rst
index 5df9694296d..47a3e9f3190 100644
--- a/routing.rst
+++ b/routing.rst
@@ -1020,6 +1020,25 @@ corresponding ``BlogPost`` object from the database using the slug.
 
     Route parameter mapping was introduced in Symfony 7.1.
 
+When mapping multiple entities from route parameters, name collisions can occur.
+In this example, the route tries to define two mappings: one for an author and one
+for a category; both using the same ``name`` parameter. This isn't allowed because
+the route ends up declaring ``name`` twice::
+
+    #[Route('/search-book/{name:author}/{name:category}')]
+
+Such routes should instead be defined using the following syntax::
+
+    #[Route('/search-book/{authorName:author.name}/{categoryName:category.name}')]
+
+This way, the route parameter names are unique (``authorName`` and ``categoryName``),
+and the "param converter" can correctly map them to controller arguments (``$author``
+and ``$category``), loading them both by their name.
+
+.. versionadded:: 7.3
+
+    This more advanced style of route parameter mapping was introduced in Symfony 7.3.
+
 More advanced mappings can be achieved using the ``#[MapEntity]`` attribute.
 Check out the :ref:`Doctrine param conversion documentation <doctrine-entity-value-resolver>`
 to learn how to customize the database queries used to fetch the object from the route

From 0d4b75575c53dd9a4bb846051462ece4d95c3c3e Mon Sep 17 00:00:00 2001
From: Jacob Dreesen <jacob@hdreesen.de>
Date: Tue, 20 May 2025 22:56:29 +0200
Subject: [PATCH 676/747] Try fixing a list in object_mapper.rst

---
 object_mapper.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/object_mapper.rst b/object_mapper.rst
index fe7db2365cf..0eed176c67d 100644
--- a/object_mapper.rst
+++ b/object_mapper.rst
@@ -149,7 +149,7 @@ You can apply the ``#[Map]`` attribute to properties to customize their mapping
 
 * ``target``: Specifies the name of the property in the target object;
 * ``source``: Specifies the name of the property in the source object (useful
-    when mapping is defined on the target, see below);
+  when mapping is defined on the target, see below);
 * ``if``: Defines a condition for mapping the property;
 * ``transform``: Applies a transformation to the value before mapping.
 

From e12256ce2df50fdf97ca28eaa866c28a2255ba97 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 22 May 2025 10:33:40 +0200
Subject: [PATCH 677/747] Rewords

---
 reference/configuration/framework.rst |  28 +++----
 security/csrf.rst                     | 108 +++++++++++++-------------
 2 files changed, 71 insertions(+), 65 deletions(-)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index 23baa21642e..464b61dd69b 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -857,36 +857,38 @@ stateless_token_ids
 
 **type**: ``array`` **default**: ``[]``
 
-The list of CSRF token ids that will use stateless CSRF protection.
+The list of CSRF token ids that will use :ref:`stateless CSRF protection <csrf-stateless-tokens>`.
 
 .. versionadded:: 7.2
 
-    This option was added in Symfony 7.2 to aid in configuring stateless CSRF protection.
+    The ``stateless_token_ids`` option was introduced in Symfony 7.2.
 
 check_header
 ............
 
 **type**: ``integer`` or ``bool`` **default**: ``false``
 
-Whether to check the CSRF token in a header in addition to a cookie when using stateless protection.
-Can be set to ``2`` (the value of the ``CHECK_ONLY_HEADER`` constant on the
-:class:`Symfony\\Component\\Security\\Csrf\\SameOriginCsrfTokenManager` class) to check only the header
-and not the cookie.
+Whether to check the CSRF token in an HTTP header in addition to the cookie when
+using :ref:`stateless CSRF protection <csrf-stateless-tokens>`. You can also set
+this to ``2`` (the value of the ``CHECK_ONLY_HEADER`` constant on the
+:class:`Symfony\\Component\\Security\\Csrf\\SameOriginCsrfTokenManager` class)
+to check only the header and ignore the cookie.
 
 .. versionadded:: 7.2
 
-    This option was added in Symfony 7.2 to aid in configuring stateless CSRF protection.
+    The ``check_header`` option was introduced in Symfony 7.2.
 
 cookie_name
 ...........
 
 **type**: ``string`` **default**: ``csrf-token``
 
-The name of the cookie (and header) to use for the double-submit when using stateless protection.
+The name of the cookie (and HTTP header) to use for the double-submit when using
+:ref:`stateless CSRF protection <csrf-stateless-tokens>`.
 
 .. versionadded:: 7.2
 
-    This option was added in Symfony 7.2 to aid in configuring stateless CSRF protection.
+    The ``cookie_name`` option was introduced in Symfony 7.2.
 
 .. _config-framework-default_locale:
 
@@ -1213,16 +1215,16 @@ field_attr
 
 **type**: ``array`` **default**: ``['data-controller' => 'csrf-protection']``
 
-This is the HTML attributes that should be added to the CSRF token field of your forms.
+HTML attributes to add to the CSRF token field of your forms.
 
 token_id
 ''''''''
 
 **type**: ``string`` **default**: ``null``
 
-This is the CSRF token id that should be used for validating the CSRF tokens of your forms.
-Note that this setting applies only to autoconfigured form types, which usually means only
-to your own form types and not to form types registered by third-party bundles.
+The CSRF token ID used to validate the CSRF tokens of your forms. This setting
+applies only to form types that use :ref:`service autoconfiguration <services-autoconfigure>`,
+which typically means your own form types, not those registered by third-party bundles.
 
 fragments
 ~~~~~~~~~
diff --git a/security/csrf.rst b/security/csrf.rst
index 2e7369d170f..b303af9511b 100644
--- a/security/csrf.rst
+++ b/security/csrf.rst
@@ -34,9 +34,9 @@ unique tokens added to forms as hidden fields. The legit server validates them t
 ensure that the request originated from the expected source and not some other
 malicious website.
 
-Anti-CSRF tokens can be managed either in a stateful way: they're put in the
-session and are unique for each user and for each kind of action, or in a
-stateless way: they're generated on the client-side.
+Anti-CSRF tokens can be managed in two ways: using a **stateful** approach,
+where tokens are stored in the session and are unique per user and action; or a
+**stateless** approach, where tokens are generated on the client side.
 
 Installation
 ------------
@@ -106,7 +106,7 @@ protected forms, among them:
   field value with it.
 
 The most effective way to cache pages that need CSRF protected forms is to use
-stateless CSRF tokens, see below.
+:ref:`stateless CSRF tokens <csrf-stateless-tokens>`, as explained below.
 
 .. _csrf-protection-forms:
 
@@ -310,6 +310,8 @@ targeted parts of the plaintext. To mitigate these attacks, and prevent an
 attacker from guessing the CSRF tokens, a random mask is prepended to the token
 and used to scramble it.
 
+.. _csrf-stateless-tokens:
+
 Stateless CSRF Tokens
 ---------------------
 
@@ -363,28 +365,31 @@ option:
             ;
         };
 
-Stateless CSRF tokens use a CSRF protection that doesn't need the session. This
-means that you can cache the entire page and still have CSRF protection.
+Stateless CSRF tokens provide protection without relying on the session. This
+allows you to fully cache pages while still protecting against CSRF attacks.
 
-When a stateless CSRF token is checked for validity, Symfony verifies the
-``Origin`` and the ``Referer`` headers of the incoming HTTP request.
+When validating a stateless CSRF token, Symfony checks the ``Origin`` and
+``Referer`` headers of the incoming HTTP request. If either header matches the
+application's target origin (i.e. its domain), the token is considered valid.
 
-If either of these headers match the target origin of the application (its domain
-name), the CSRF token is considered valid. This relies on the app being able to
-know its own target origin. Don't miss configuring your reverse proxy if you're
-behind one. See :doc:`/deployment/proxies`.
+This mechanism relies on the application being able to determine its own origin.
+If you're behind a reverse proxy, make sure it's properly configured. See
+:doc:`/deployment/proxies`.
 
 Using a Default Token ID
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
-While stateful CSRF tokens are better seggregated per form or action, stateless
-ones don't need many token identifiers. In the previous example, ``authenticate``
-and ``logout`` are listed because they're the default identifiers used by the
-Symfony Security component. The ``submit`` identifier is then listed so that
-form types defined by the application can use it by default. The following
-configuration - which applies only to form types declared using autofiguration
-(the default way to declare *your* services) - will make your form types use the
-``submit`` token identifier by default:
+Stateful CSRF tokens are typically scoped per form or action, while stateless
+tokens don't require many identifiers.
+
+In the example above, the ``authenticate`` and ``logout`` identifiers are listed
+because they are used by default in the Symfony Security component. The ``submit``
+identifier is included so that form types defined by the application can also use
+CSRF protection by default.
+
+The following configuration applies only to form types registered via
+:ref:`autoconfiguration <services-autoconfigure>` (which is the default for your
+own services), and it sets ``submit`` as their default token identifier:
 
 .. configuration-block::
 
@@ -433,41 +438,40 @@ option will use the stateless CSRF protection.
 Generating CSRF Token Using Javascript
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-In addition to the ``Origin`` and ``Referer`` headers, stateless CSRF protection
-also checks a cookie and a header (named ``csrf-token`` by default, see the
-:ref:`CSRF configuration reference <reference-framework-csrf-protection>`).
-
-These extra checks are part of defense-in-depth strategies provided by the
-stateless CSRF protection. They are optional and they require
-`some JavaScript`_ to be activated. This JavaScript is responsible for generating
-a crypto-safe random token when a form is submitted, then putting the token in
-the hidden CSRF field of the form and submitting it also as a cookie and header.
-On the server-side, the CSRF token is validated by checking the cookie and header
-values. This "double-submit" protection relies on the same-origin policy
-implemented by browsers and is strengthened by regenerating the token at every
-form submission - which prevents cookie fixation issues - and by using
-``samesite=strict`` and ``__Host-`` cookies, which make them domain-bound and
-HTTPS-only.
-
-Note that the default snippet of JavaScript provided by Symfony requires that
-the hidden CSRF form field is either named ``_csrf_token``, or that it has the
-``data-controller="csrf-protection"`` attribute. You can of course take
-inspiration from this snippet to write your own, provided you follow the same
-protocol.
-
-As a last measure, a behavioral check is added on the server-side to ensure that
-the validation method cannot be downgraded: if and only if a session is already
-available, successful "double-submit" is remembered and is then required for
-subsequent requests. This prevents attackers from exploiting potentially reduced
-validation checks once cookie and/or header validation has been confirmed as
-effective (they're optional by default as explained above).
+In addition to the ``Origin`` and ``Referer`` HTTP headers, stateless CSRF protection
+can also validate tokens using a cookie and a header (named ``csrf-token`` by
+default; see the :ref:`CSRF configuration reference <reference-framework-csrf-protection>`).
+
+These additional checks are part of the **defense-in-depth** strategy provided by
+stateless CSRF protection. They are optional and require `some JavaScript`_ to
+be enabled. This JavaScript generates a cryptographically secure random token
+when a form is submitted. It then inserts the token into the form's hidden CSRF
+field and sends it in both a cookie and a request header.
+
+On the server side, CSRF token validation compares the values in the cookie and
+the header. This "double-submit" protection relies on the browser's same-origin
+policy and is further hardened by:
+
+* generating a new token for each submission (to prevent cookie fixation);
+* using ``samesite=strict`` and ``__Host-`` cookie attributes (to enforce HTTPS
+  and limit the cookie to the current domain).
+
+By default, the Symfony JavaScript snippet expects the hidden CSRF field to be
+named ``_csrf_token`` or to include the ``data-controller="csrf-protection"``
+attribute. You can adapt this logic to your needs as long as the same protocol
+is followed.
+
+To prevent validation from being downgraded, an extra behavioral check is performed:
+if (and only if) a session already exists, successful "double-submit" is remembered
+and becomes required for future requests. This ensures that once the optional cookie/header
+validation has been proven effective, it remains enforced for that session.
 
 .. note::
 
-    Enforcing successful "double-submit" for every requests is not recommended as
-    as it could lead to a broken user experience. The opportunistic approach
-    described above is preferred because it allows the application to gracefully
-    degrade to ``Origin`` / ``Referer`` checks when JavaScript is not available.
+    Enforcing "double-submit" validation on all requests is not recommended,
+    as it may lead to a broken user experience. The opportunistic approach
+    described above is preferred, allowing the application to gracefully
+    fall back to ``Origin`` / ``Referer`` checks when JavaScript is unavailable.
 
 .. _`Cross-site request forgery`: https://en.wikipedia.org/wiki/Cross-site_request_forgery
 .. _`BREACH`: https://en.wikipedia.org/wiki/BREACH

From f97b8d59f092fcbc14ea54daa9b59adfb33093ce Mon Sep 17 00:00:00 2001
From: Santiago San Martin <sanmartindev@gmail.com>
Date: Sun, 18 May 2025 11:52:46 -0300
Subject: [PATCH 678/747] [Security]
 iscsrftokenvalid-attribute-controller-usage

---
 security/csrf.rst | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/security/csrf.rst b/security/csrf.rst
index b303af9511b..cc1ab42482d 100644
--- a/security/csrf.rst
+++ b/security/csrf.rst
@@ -281,6 +281,20 @@ Suppose you want a CSRF token per item, so in the template you have something li
         <button type="submit">Delete item</button>
     </form>
 
+In addition :class:`Symfony\\Component\\Security\\Http\\Attribute\\IsCsrfTokenValid`
+attribute can be applied to a controller class.
+This will cause the CSRF token validation to be executed for all routes defined within the controller::
+
+    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+    use Symfony\Component\Security\Http\Attribute\IsCsrfTokenValid;
+    // ...
+
+    #[IsCsrfTokenValid('controller')]
+    final class FooController extends AbstractController
+    {
+        // ...
+    }
+
 The :class:`Symfony\\Component\\Security\\Http\\Attribute\\IsCsrfTokenValid`
 attribute also accepts an :class:`Symfony\\Component\\ExpressionLanguage\\Expression`
 object evaluated to the id::

From 83b30927029e9f60cc4c4a77edba2bbd6bda5f2f Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 22 May 2025 17:45:51 +0200
Subject: [PATCH 679/747] Minor tweaks

---
 security/csrf.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/security/csrf.rst b/security/csrf.rst
index cc1ab42482d..b72c7cc2526 100644
--- a/security/csrf.rst
+++ b/security/csrf.rst
@@ -281,16 +281,16 @@ Suppose you want a CSRF token per item, so in the template you have something li
         <button type="submit">Delete item</button>
     </form>
 
-In addition :class:`Symfony\\Component\\Security\\Http\\Attribute\\IsCsrfTokenValid`
-attribute can be applied to a controller class.
-This will cause the CSRF token validation to be executed for all routes defined within the controller::
+This attribute can also be applied to a controller class. When used this way,
+the CSRF token validation will be applied to **all actions** defined in that
+controller::
 
     use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
     use Symfony\Component\Security\Http\Attribute\IsCsrfTokenValid;
     // ...
 
-    #[IsCsrfTokenValid('controller')]
-    final class FooController extends AbstractController
+    #[IsCsrfTokenValid('the token ID')]
+    final class SomeController extends AbstractController
     {
         // ...
     }

From 2c33c3623d631fc631bf75d3a5dcfbfb3d2c259f Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 23 May 2025 09:12:33 +0200
Subject: [PATCH 680/747] [FrameworkBundle] Enable controller service with
 #[Route] attribute

---
 controller/service.rst | 84 +++++++++++++++++++++++++++++-------------
 routing.rst            |  2 +
 2 files changed, 61 insertions(+), 25 deletions(-)

diff --git a/controller/service.rst b/controller/service.rst
index 88af093ff29..cf83e066a19 100644
--- a/controller/service.rst
+++ b/controller/service.rst
@@ -7,11 +7,65 @@ and your controllers extend the `AbstractController`_ class, they *are* automati
 registered as services. This means you can use dependency injection like any
 other normal service.
 
-If your controllers don't extend the `AbstractController`_ class, you must
-explicitly mark your controller services as ``public``. Alternatively, you can
-apply the ``controller.service_arguments`` tag to your controller services. This
-will make the tagged services ``public`` and will allow you to inject services
-in method parameters:
+If you prefer to not extend the ``AbstractController`` class, you can register
+your controllers as services in several ways:
+
+#. Using the ``#[Route]`` attribute;
+#. Using the ``#[AsController]`` attribute;
+#. Using the ``controller.service_arguments`` service tag.
+
+Using the ``#[Route]`` Attribute
+--------------------------------
+
+When using :ref:`the #[Route] attribute <routing-route-attributes>` to define
+routes on any PHP class, Symfony treats that class as a controller. It registers
+it as a public, non-lazy service and enables service argument injection in all
+its methods.
+
+This is the simplest and recommended way to register controllers as services
+when not extending the base controller class.
+
+.. versionadded:: 7.3
+
+    The feature to register controllers as services when using the ``#[Route]``
+    attribute was introduced in Symfony 7.3.
+
+Using the ``#[AsController]`` Attribute
+---------------------------------------
+
+If you prefer, you can use the ``#[AsController]`` PHP attribute to automatically
+apply the ``controller.service_arguments`` tag to your controller services::
+
+    // src/Controller/HelloController.php
+    namespace App\Controller;
+
+    use Symfony\Component\HttpFoundation\Response;
+    use Symfony\Component\HttpKernel\Attribute\AsController;
+    use Symfony\Component\Routing\Attribute\Route;
+
+    #[AsController]
+    class HelloController
+    {
+        #[Route('/hello', name: 'hello', methods: ['GET'])]
+        public function index(): Response
+        {
+            // ...
+        }
+    }
+
+.. tip::
+
+    When using the ``#[Route]`` attribute, Symfony already registers the controller
+    class as a service, so using the ``#[AsController]`` attribute is redundant.
+
+Using the ``controller.service_arguments`` Service Tag
+------------------------------------------------------
+
+If your controllers don't extend the `AbstractController`_ class and you don't
+use the ``#[AsController]`` or ``#[Route]`` attributes, you must register the
+controllers as public services manually and apply the ``controller.service_arguments``
+:doc:`service tag </service_container/tags>` to enable service injection in
+controller actions:
 
 .. configuration-block::
 
@@ -58,26 +112,6 @@ in method parameters:
             calls:
                 - [setContainer, ['@abstract_controller.locator']]
 
-If you prefer, you can use the ``#[AsController]`` PHP attribute to automatically
-apply the ``controller.service_arguments`` tag to your controller services::
-
-    // src/Controller/HelloController.php
-    namespace App\Controller;
-
-    use Symfony\Component\HttpFoundation\Response;
-    use Symfony\Component\HttpKernel\Attribute\AsController;
-    use Symfony\Component\Routing\Attribute\Route;
-
-    #[AsController]
-    class HelloController
-    {
-        #[Route('/hello', name: 'hello', methods: ['GET'])]
-        public function index(): Response
-        {
-            // ...
-        }
-    }
-
 Registering your controller as a service is the first step, but you also need to
 update your routing config to reference the service properly, so that Symfony
 knows to use it.
diff --git a/routing.rst b/routing.rst
index e634a410c37..b8b2437ee3e 100644
--- a/routing.rst
+++ b/routing.rst
@@ -18,6 +18,8 @@ your favorite.
 :ref:`Symfony recommends attributes <best-practice-controller-attributes>`
 because it's convenient to put the route and controller in the same place.
 
+.. _routing-route-attributes:
+
 Creating Routes as Attributes
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

From 310783b4c0a9f1b329c010b1c20dcdfed5643400 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 23 May 2025 09:55:29 +0200
Subject: [PATCH 681/747] [Translation] Don't mention the abandoned Doctrine
 Translatable behavior

---
 translation.rst | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/translation.rst b/translation.rst
index b9fbdd7e0f6..f41d0cb6489 100644
--- a/translation.rst
+++ b/translation.rst
@@ -599,8 +599,7 @@ Translations of Doctrine Entities
 
 Unlike the contents of templates, it's not practical to translate the contents
 stored in Doctrine Entities using translation catalogs. Instead, use the
-Doctrine `Translatable Extension`_ or the `Translatable Behavior`_. For more
-information, read the documentation of those libraries.
+Doctrine `Translatable Extension`_.
 
 Custom Translation Resources
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1599,7 +1598,6 @@ Learn more
 .. _`ISO 3166-1 alpha-2`: https://en.wikipedia.org/wiki/ISO_3166-1#Current_codes
 .. _`ISO 639-1`: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
 .. _`Translatable Extension`: https://github.com/doctrine-extensions/DoctrineExtensions/blob/main/doc/translatable.md
-.. _`Translatable Behavior`: https://github.com/KnpLabs/DoctrineBehaviors
 .. _`Custom Language Name setting`: https://docs.lokalise.com/en/articles/1400492-uploading-files#custom-language-codes
 .. _`ICU resource bundle`: https://github.com/unicode-org/icu-docs/blob/main/design/bnf_rb.txt
 .. _`Portable object format`: https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html

From 203c0f8e21071ad1396ef12686a344e39f47a1bc Mon Sep 17 00:00:00 2001
From: MrYamous <matt.lempereur@gmail.com>
Date: Tue, 25 Feb 2025 20:45:57 +0100
Subject: [PATCH 682/747] [Security] Add ability for voters to explain their
 vote

---
 security.rst        |  8 +++++++-
 security/voters.rst | 30 +++++++++++++++++++++++-------
 2 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/security.rst b/security.rst
index ca910765be0..5a6fc15ae2e 100644
--- a/security.rst
+++ b/security.rst
@@ -2704,13 +2704,14 @@ anonymous users access by checking if there is no user set on the token::
     // ...
     use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
     use Symfony\Component\Security\Core\Authentication\User\UserInterface;
+    use Symfony\Component\Security\Core\Authorization\Voter\Vote;
     use Symfony\Component\Security\Core\Authorization\Voter\Voter;
 
     class PostVoter extends Voter
     {
         // ...
 
-        protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
+        protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token, ?Vote $vote = null): bool
         {
             // ...
 
@@ -2722,6 +2723,11 @@ anonymous users access by checking if there is no user set on the token::
         }
     }
 
+.. versionadded:: 7.3
+    
+    The `$vote` parameter in the :method:`Symfony\\Component\\Security\\Core\\Authorization\\Voter\\VoterInterface::voteOnAttribute` method
+    was introduced in Symfony 7.3.
+
 Setting Individual User Permissions
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/security/voters.rst b/security/voters.rst
index e7452fadf99..ba4c96fe6fd 100644
--- a/security/voters.rst
+++ b/security/voters.rst
@@ -40,14 +40,20 @@ or extend :class:`Symfony\\Component\\Security\\Core\\Authorization\\Voter\\Vote
 which makes creating a voter even easier::
 
     use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+    use Symfony\Component\Security\Core\Authorization\Voter\Vote;
     use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
 
     abstract class Voter implements VoterInterface
     {
         abstract protected function supports(string $attribute, mixed $subject): bool;
-        abstract protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool;
+        abstract protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool;
     }
 
+.. versionadded:: 7.3
+    
+    The `$vote` parameter in the :method:`Symfony\\Component\\Security\\Core\\Authorization\\Voter\\VoterInterface::voteOnAttribute` method
+    was introduced in Symfony 7.3.
+
 .. _how-to-use-the-voter-in-a-controller:
 
 .. tip::
@@ -140,6 +146,7 @@ would look like this::
     use App\Entity\Post;
     use App\Entity\User;
     use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+    use Symfony\Component\Security\Core\Authorization\Voter\Vote;
     use Symfony\Component\Security\Core\Authorization\Voter\Voter;
 
     class PostVoter extends Voter
@@ -163,12 +170,14 @@ would look like this::
             return true;
         }
 
-        protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
+        protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool
         {
             $user = $token->getUser();
+            $vote ??= new Vote();
 
             if (!$user instanceof User) {
                 // the user must be logged in; if not, deny access
+                $vote->reasons[] = 'The user is not logged in.';
                 return false;
             }
 
@@ -197,7 +206,13 @@ would look like this::
         private function canEdit(Post $post, User $user): bool
         {
             // this assumes that the Post object has a `getOwner()` method
-            return $user === $post->getOwner();
+            if ($user === $post->getOwner()) {
+                return true;
+            }
+
+            $vote->reasons[] = 'You are not the owner of the Post.';
+
+            return false;
         }
     }
 
@@ -215,11 +230,12 @@ To recap, here's what's expected from the two abstract methods:
     return ``true`` if the attribute is ``view`` or ``edit`` and if the object is
     a ``Post`` instance.
 
-``voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token)``
+``voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null)``
     If you return ``true`` from ``supports()``, then this method is called. Your
     job is to return ``true`` to allow access and ``false`` to deny access.
-    The ``$token`` can be used to find the current user object (if any). In this
-    example, all of the complex business logic is included to determine access.
+    The ``$token`` can be used to find the current user object (if any). The ``$vote``
+    argument can be used to add a reason to the vote. In this example, all of the
+    complex business logic is included to determine access.
 
 .. _declaring-the-voter-as-a-service:
 
@@ -256,7 +272,7 @@ with ``ROLE_SUPER_ADMIN``::
         ) {
         }
 
-        protected function voteOnAttribute($attribute, mixed $subject, TokenInterface $token): bool
+        protected function voteOnAttribute($attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool
         {
             // ...
 

From ef9c945fe180c9a7a459b37e6a13fd0f63c9678d Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 23 May 2025 10:24:48 +0200
Subject: [PATCH 683/747] Minor tweaks

---
 security.rst        |  4 ++--
 security/voters.rst | 22 ++++++++++++----------
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/security.rst b/security.rst
index 8b1c8a96e69..9d2df6165d0 100644
--- a/security.rst
+++ b/security.rst
@@ -2715,8 +2715,8 @@ anonymous users access by checking if there is no user set on the token::
 
 .. versionadded:: 7.3
     
-    The `$vote` parameter in the :method:`Symfony\\Component\\Security\\Core\\Authorization\\Voter\\VoterInterface::voteOnAttribute` method
-    was introduced in Symfony 7.3.
+    The ``$vote`` argument of the ``voteOnAttribute()`` method was introduced
+    in Symfony 7.3.
 
 Setting Individual User Permissions
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/security/voters.rst b/security/voters.rst
index ba4c96fe6fd..2b4a5af54e2 100644
--- a/security/voters.rst
+++ b/security/voters.rst
@@ -51,8 +51,8 @@ which makes creating a voter even easier::
 
 .. versionadded:: 7.3
     
-    The `$vote` parameter in the :method:`Symfony\\Component\\Security\\Core\\Authorization\\Voter\\VoterInterface::voteOnAttribute` method
-    was introduced in Symfony 7.3.
+    The ``$vote`` argument of the ``voteOnAttribute()`` method was introduced
+    in Symfony 7.3.
 
 .. _how-to-use-the-voter-in-a-controller:
 
@@ -173,11 +173,10 @@ would look like this::
         protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool
         {
             $user = $token->getUser();
-            $vote ??= new Vote();
 
             if (!$user instanceof User) {
                 // the user must be logged in; if not, deny access
-                $vote->reasons[] = 'The user is not logged in.';
+                $vote?->addReason('The user is not logged in.');
                 return false;
             }
 
@@ -205,12 +204,15 @@ would look like this::
 
         private function canEdit(Post $post, User $user): bool
         {
-            // this assumes that the Post object has a `getOwner()` method
-            if ($user === $post->getOwner()) {
+            // this assumes that the Post object has a `getAuthor()` method
+            if ($user === $post->getAuthor()) {
                 return true;
             }
 
-            $vote->reasons[] = 'You are not the owner of the Post.';
+            $vote?->addReason(sprintf(
+                'The logged in user (username: %s) is not the author of this post (id: %d).',
+                $user->getUsername(), $post->getId()
+            ));
 
             return false;
         }
@@ -233,9 +235,9 @@ To recap, here's what's expected from the two abstract methods:
 ``voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null)``
     If you return ``true`` from ``supports()``, then this method is called. Your
     job is to return ``true`` to allow access and ``false`` to deny access.
-    The ``$token`` can be used to find the current user object (if any). The ``$vote``
-    argument can be used to add a reason to the vote. In this example, all of the
-    complex business logic is included to determine access.
+    The ``$token`` can be used to find the current user object (if any).
+    The ``$vote`` argument can be used to provide an explanation for the vote.
+    This explanation is included in log messages and on exception pages.
 
 .. _declaring-the-voter-as-a-service:
 

From a2c83bfb2fc02162dcc2e13a5d67d6f187c861a8 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 23 May 2025 10:50:10 +0200
Subject: [PATCH 684/747] Minor tweaks

---
 workflow.rst | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/workflow.rst b/workflow.rst
index 544f775cce0..482fe8ed273 100644
--- a/workflow.rst
+++ b/workflow.rst
@@ -1306,11 +1306,11 @@ In Twig templates, metadata is available via the ``workflow_metadata()`` functio
         </ul>
     </p>
 
-Adding Custom Definition Validators
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Validating Workflow Definitions
+-------------------------------
 
-Sometimes, you may want to add custom logics to validate your workflow definition.
-To do this, you need to implement the
+Symfony allows you to validate workflow definitions using your own custom logic.
+To do so, create a class that implements the
 :class:`Symfony\\Component\\Workflow\\Validator\\DefinitionValidatorInterface`::
 
     namespace App\Workflow\Validator;
@@ -1326,11 +1326,12 @@ To do this, you need to implement the
             if (!$definition->getMetadataStore()->getMetadata('title')) {
                 throw new InvalidDefinitionException(sprintf('The workflow metadata title is missing in Workflow "%s".', $name));
             }
+
+            // ...
         }
     }
 
-Once your definition validator is implemented, you can configure your workflow to use
-it:
+After implementing your validator, configure your workflow to use it:
 
 .. configuration-block::
 
@@ -1340,7 +1341,7 @@ it:
         framework:
             workflows:
                 blog_publishing:
-                    # ... previous configuration
+                    # ...
 
                     definition_validators:
                         - App\Workflow\Validator\BlogPublishingValidator
@@ -1357,7 +1358,7 @@ it:
         >
             <framework:config>
                 <framework:workflow name="blog_publishing">
-                    <!-- ... previous configuration -->
+                    <!-- ... -->
                     <framework:definition-validators>App\Workflow\Validator\BlogPublishingValidator</framework:definition-validators>
                 </framework:workflow>
             </framework:config>
@@ -1370,7 +1371,7 @@ it:
 
         return static function (FrameworkConfig $framework): void {
             $blogPublishing = $framework->workflows()->workflows('blog_publishing');
-            // ... previous configuration
+            // ...
 
             $blogPublishing->definitionValidators([
                 App\Workflow\Validator\BlogPublishingValidator::class
@@ -1379,11 +1380,12 @@ it:
             // ...
         };
 
-The ``BlogPublishingValidator`` definition validator will be executed during the container compilation.
+The ``BlogPublishingValidator`` will be executed during container compilation
+to validate the workflow definition.
 
 .. versionadded:: 7.3
 
-    Support for defining custom workflow definition validators was introduced in Symfony 7.3.
+    Support for workflow definition validators was introduced in Symfony 7.3.
 
 Learn more
 ----------

From faa30fc32ec1a0360baa201db0afd7edcf4861bb Mon Sep 17 00:00:00 2001
From: Thomas Landauer <thomas@landauer.at>
Date: Sun, 25 May 2025 11:52:44 +0200
Subject: [PATCH 685/747] [Security] Stateless CSRF is enabled by default in
 7.2

Page: https://symfony.com/doc/current/security/csrf.html#stateless-csrf-tokens

Info is taken from https://github.com/symfony/recipes/blob/main/symfony/form/7.2/config/packages/csrf.yaml
---
 security/csrf.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/security/csrf.rst b/security/csrf.rst
index b72c7cc2526..07e0671f07b 100644
--- a/security/csrf.rst
+++ b/security/csrf.rst
@@ -331,9 +331,9 @@ Stateless CSRF Tokens
 
 .. versionadded:: 7.2
 
-    Stateless anti-CSRF protection was introduced in Symfony 7.2.
+    Stateless anti-CSRF protection was introduced in Symfony 7.2, and set as default.
 
-By default CSRF tokens are stateful, which means they're stored in the session.
+Traditionally CSRF tokens are stateful, which means they're stored in the session.
 But some token ids can be declared as stateless using the ``stateless_token_ids``
 option:
 

From 7d13bac560ff6506c3eaaf734aa388d7f7d3bf19 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 27 May 2025 08:28:54 +0200
Subject: [PATCH 686/747] Minor tweak

---
 security/csrf.rst | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/security/csrf.rst b/security/csrf.rst
index 07e0671f07b..29fe96fa689 100644
--- a/security/csrf.rst
+++ b/security/csrf.rst
@@ -331,11 +331,12 @@ Stateless CSRF Tokens
 
 .. versionadded:: 7.2
 
-    Stateless anti-CSRF protection was introduced in Symfony 7.2, and set as default.
+    Stateless anti-CSRF protection was introduced in Symfony 7.2.
 
-Traditionally CSRF tokens are stateful, which means they're stored in the session.
-But some token ids can be declared as stateless using the ``stateless_token_ids``
-option:
+Traditionally, CSRF tokens are stateful, meaning they're stored in the session.
+However, some token IDs can be declared as stateless using the
+``stateless_token_ids`` option. Stateless CSRF tokens are enabled by default
+in applications using :ref:`Symfony Flex <symfony-flex>`.
 
 .. configuration-block::
 

From 4e67b7324679f9fbffa24aad0d0635c41be8285a Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 27 May 2025 09:21:16 +0200
Subject: [PATCH 687/747] Reword

---
 messenger.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index e37f075518a..97b95565fa7 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2468,7 +2468,8 @@ Possible options to configure with tags are:
     Name of the method that will process the message.
 
 ``priority``
-    Priority of the handler when multiple handlers can process the same message; higher values will be processed first.
+    Defines the order in which the handler is executed when multiple handlers
+    can process the same message; those with higher priority run first.
 
 .. _handler-subscriber-options:
 

From 01f381305940492ddbbfc0ab54a30db383971ac4 Mon Sep 17 00:00:00 2001
From: ifiroth <97906657+ifiroth@users.noreply.github.com>
Date: Tue, 27 May 2025 11:11:06 +0200
Subject: [PATCH 688/747] Update voters.rst

I think you're missing an argument here
---
 security/voters.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/security/voters.rst b/security/voters.rst
index 2b4a5af54e2..f20e1de62af 100644
--- a/security/voters.rst
+++ b/security/voters.rst
@@ -186,7 +186,7 @@ would look like this::
 
             return match($attribute) {
                 self::VIEW => $this->canView($post, $user),
-                self::EDIT => $this->canEdit($post, $user),
+                self::EDIT => $this->canEdit($post, $user, $vote),
                 default => throw new \LogicException('This code should not be reached!')
             };
         }
@@ -202,7 +202,7 @@ would look like this::
             return !$post->isPrivate();
         }
 
-        private function canEdit(Post $post, User $user): bool
+        private function canEdit(Post $post, User $user, ?Vote $vote): bool
         {
             // this assumes that the Post object has a `getAuthor()` method
             if ($user === $post->getAuthor()) {

From 91a952566fc2a93c08cb162eeddb1fc83edef0ab Mon Sep 17 00:00:00 2001
From: NanoSector <rick@nanosector.nl>
Date: Mon, 24 Mar 2025 21:31:11 +0100
Subject: [PATCH 689/747] [Doctrine] entityvalueresolver target entities

---
 doctrine.rst                       | 22 +++++++++++++++++
 doctrine/resolve_target_entity.rst | 39 +++++++++++++++++-------------
 2 files changed, 44 insertions(+), 17 deletions(-)

diff --git a/doctrine.rst b/doctrine.rst
index 171f8a3348a..876aaa3065d 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -780,6 +780,28 @@ variable. Let's say you want the first or the last comment of a product dependin
         Comment $comment
     ): Response {
     }
+    
+.. _doctrine-entity-value-resolver-resolve-target-entities:
+    
+Fetch via Interfaces
+~~~~~~~~~~~~~~~~~~~~
+
+Suppose your ``Product`` object implements an interface called ``ProductInterface``.
+If you want to decouple your controllers from your entity implementations, you can instead reference entities via an interface.
+To do this, first you need to configure the :doc:`resolve_target_entities option </doctrine/resolve_target_entity>`.
+        
+Your controller can then reference the Product entity by its interface instead::
+
+        public function show(
+            #[MapEntity]
+            ProductInterface $product
+        ): Response {
+            // ...
+        }
+        
+.. versionadded:: 7.3
+
+    Support for ``resolve_target_entites`` in the ``EntityValueResolver`` was introduced in Symfony 7.3.
 
 MapEntity Options
 ~~~~~~~~~~~~~~~~~
diff --git a/doctrine/resolve_target_entity.rst b/doctrine/resolve_target_entity.rst
index 5ae6475a957..c55b27f6463 100644
--- a/doctrine/resolve_target_entity.rst
+++ b/doctrine/resolve_target_entity.rst
@@ -1,30 +1,35 @@
-How to Define Relationships with Abstract Classes and Interfaces
-================================================================
+Referencing Entities with Abstract Classes and Interfaces
+=========================================================
 
-One of the goals of bundles is to create discrete bundles of functionality
-that do not have many (if any) dependencies, allowing you to use that
-functionality in other applications without including unnecessary items.
+In applications where functionality is segregated with minimal concrete dependencies
+between the various layers, such as monoliths which are split into multiple modules,
+it might be hard to prevent hard dependencies on entities between modules.
 
 Doctrine 2.2 includes a new utility called the ``ResolveTargetEntityListener``,
 that functions by intercepting certain calls inside Doctrine and rewriting
 ``targetEntity`` parameters in your metadata mapping at runtime. It means that
-in your bundle you are able to use an interface or abstract class in your
-mappings and expect correct mapping to a concrete entity at runtime.
+you are able to use an interface or abstract class in your mappings and expect
+correct mapping to a concrete entity at runtime.
 
 This functionality allows you to define relationships between different entities
 without making them hard dependencies.
 
+.. tip::
+
+    Starting with Symfony 7.3, this functionality also works with the ``EntityValueResolver``.
+    See :ref:`doctrine-entity-value-resolver-resolve-target-entities` for more details.
+
 Background
 ----------
 
-Suppose you have an InvoiceBundle which provides invoicing functionality
-and a CustomerBundle that contains customer management tools. You want
-to keep these separated, because they can be used in other systems without
-each other, but for your application you want to use them together.
+Suppose you have an application which provides two modules; an Invoice module which
+provides invoicing functionality, and a Customer module that contains customer management
+tools. You want to keep dependencies between these modules separated, because they should
+not be aware of the other module's implementation details.
 
-In this case, you have an ``Invoice`` entity with a relationship to a
-non-existent object, an ``InvoiceSubjectInterface``. The goal is to get
-the ``ResolveTargetEntityListener`` to replace any mention of the interface
+In this case, you have an ``Invoice`` entity with a relationship to the interface
+``InvoiceSubjectInterface``. This is not recognized as a valid entity by Doctrine.
+The goal is to get the ``ResolveTargetEntityListener`` to replace any mention of the interface
 with a real object that implements that interface.
 
 Set up
@@ -89,7 +94,7 @@ An InvoiceSubjectInterface::
         public function getName(): string;
     }
 
-Next, you need to configure the listener, which tells the DoctrineBundle
+Next, you need to configure the ``resolve_target_entities`` option, which tells the DoctrineBundle
 about the replacement:
 
 .. configuration-block::
@@ -141,6 +146,6 @@ Final Thoughts
 --------------
 
 With the ``ResolveTargetEntityListener``, you are able to decouple your
-bundles, keeping them usable by themselves, but still being able to
+modules, keeping them usable by themselves, but still being able to
 define relationships between different objects. By using this method,
-your bundles will end up being easier to maintain independently.
+your modules will end up being easier to maintain independently.

From e6ba3a96ec8c28f692dedb1bc22a423868aad574 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 27 May 2025 12:02:55 +0200
Subject: [PATCH 690/747] Rewords

---
 doctrine.rst                       | 28 +++++++------
 doctrine/resolve_target_entity.rst | 67 ++++++++++++++----------------
 2 files changed, 48 insertions(+), 47 deletions(-)

diff --git a/doctrine.rst b/doctrine.rst
index e66488beefd..ecaf675df08 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -789,22 +789,26 @@ variable. Let's say you want the first or the last comment of a product dependin
 Fetch via Interfaces
 ~~~~~~~~~~~~~~~~~~~~
 
-Suppose your ``Product`` object implements an interface called ``ProductInterface``.
-If you want to decouple your controllers from your entity implementations, you can instead reference entities via an interface.
-To do this, first you need to configure the :doc:`resolve_target_entities option </doctrine/resolve_target_entity>`.
-        
-Your controller can then reference the Product entity by its interface instead::
+Suppose your ``Product`` class implements an interface called ``ProductInterface``.
+If you want to decouple your controllers from the concrete entity implementation,
+you can reference the entity by its interface instead.
 
-        public function show(
-            #[MapEntity]
-            ProductInterface $product
-        ): Response {
-            // ...
-        }
+To enable this, first configure the
+:doc:`resolve_target_entities option </doctrine/resolve_target_entity>`.
+Then, your controller can type-hint the interface, and the entity will be
+resolved automatically::
+
+    public function show(
+        #[MapEntity]
+        ProductInterface $product
+    ): Response {
+        // ...
+    }
         
 .. versionadded:: 7.3
 
-    Support for ``resolve_target_entites`` in the ``EntityValueResolver`` was introduced in Symfony 7.3.
+    Support for target entity resolution in the ``EntityValueResolver`` was
+    introduced Symfony 7.3
 
 MapEntity Options
 ~~~~~~~~~~~~~~~~~
diff --git a/doctrine/resolve_target_entity.rst b/doctrine/resolve_target_entity.rst
index c55b27f6463..1495f475628 100644
--- a/doctrine/resolve_target_entity.rst
+++ b/doctrine/resolve_target_entity.rst
@@ -1,44 +1,45 @@
 Referencing Entities with Abstract Classes and Interfaces
 =========================================================
 
-In applications where functionality is segregated with minimal concrete dependencies
-between the various layers, such as monoliths which are split into multiple modules,
-it might be hard to prevent hard dependencies on entities between modules.
+In applications where functionality is organized in layers or modules with
+minimal concrete dependencies, such as monoliths split into multiple modules,
+it can be challenging to avoid tight coupling between entities.
 
-Doctrine 2.2 includes a new utility called the ``ResolveTargetEntityListener``,
-that functions by intercepting certain calls inside Doctrine and rewriting
-``targetEntity`` parameters in your metadata mapping at runtime. It means that
-you are able to use an interface or abstract class in your mappings and expect
-correct mapping to a concrete entity at runtime.
+Doctrine provides a utility called the ``ResolveTargetEntityListener`` to solve
+this issue. It works by intercepting certain calls within Doctrine and rewriting
+``targetEntity`` parameters in your metadata mapping at runtime. This allows you
+to reference an interface or abstract class in your mappings and have it resolved
+to a concrete entity at runtime.
 
-This functionality allows you to define relationships between different entities
-without making them hard dependencies.
+This makes it possible to define relationships between entities without
+creating hard dependencies. This feature also works with the ``EntityValueResolver``
+:ref:`as explained in the main Doctrine article <doctrine-entity-value-resolver-resolve-target-entities>`.
 
-.. tip::
+.. versionadded:: 7.3
 
-    Starting with Symfony 7.3, this functionality also works with the ``EntityValueResolver``.
-    See :ref:`doctrine-entity-value-resolver-resolve-target-entities` for more details.
+    Support for target entity resolution in the ``EntityValueResolver`` was
+    introduced Symfony 7.3
 
 Background
 ----------
 
-Suppose you have an application which provides two modules; an Invoice module which
-provides invoicing functionality, and a Customer module that contains customer management
-tools. You want to keep dependencies between these modules separated, because they should
-not be aware of the other module's implementation details.
+Suppose you have an application with two modules: an Invoice module that
+provides invoicing functionality, and a Customer module that handles customer
+management. You want to keep these modules decoupled, so that neither is aware
+of the other's implementation details.
 
-In this case, you have an ``Invoice`` entity with a relationship to the interface
-``InvoiceSubjectInterface``. This is not recognized as a valid entity by Doctrine.
-The goal is to get the ``ResolveTargetEntityListener`` to replace any mention of the interface
-with a real object that implements that interface.
+In this case, your ``Invoice`` entity has a relationship to the interface
+``InvoiceSubjectInterface``. Since interfaces are not valid Doctrine entities,
+the goal is to use the ``ResolveTargetEntityListener`` to replace all
+references to this interface with a concrete class that implements it.
 
 Set up
 ------
 
-This article uses the following two basic entities (which are incomplete for
-brevity) to explain how to set up and use the ``ResolveTargetEntityListener``.
+This article uses two basic (incomplete) entities to demonstrate how to set up
+and use the ``ResolveTargetEntityListener``.
 
-A Customer entity::
+A ``Customer`` entity::
 
     // src/Entity/Customer.php
     namespace App\Entity;
@@ -55,7 +56,7 @@ A Customer entity::
         // are already implemented in the BaseCustomer
     }
 
-An Invoice entity::
+An ``Invoice`` entity::
 
     // src/Entity/Invoice.php
     namespace App\Entity;
@@ -63,9 +64,6 @@ An Invoice entity::
     use App\Model\InvoiceSubjectInterface;
     use Doctrine\ORM\Mapping as ORM;
 
-    /**
-     * Represents an Invoice.
-     */
     #[ORM\Entity]
     #[ORM\Table(name: 'invoice')]
     class Invoice
@@ -74,7 +72,7 @@ An Invoice entity::
         protected InvoiceSubjectInterface $subject;
     }
 
-An InvoiceSubjectInterface::
+The interface representing the subject used in the invoice::
 
     // src/Model/InvoiceSubjectInterface.php
     namespace App\Model;
@@ -94,8 +92,8 @@ An InvoiceSubjectInterface::
         public function getName(): string;
     }
 
-Next, you need to configure the ``resolve_target_entities`` option, which tells the DoctrineBundle
-about the replacement:
+Now configure the ``resolve_target_entities`` option to tell Doctrine
+how to replace the interface with the concrete class:
 
 .. configuration-block::
 
@@ -145,7 +143,6 @@ about the replacement:
 Final Thoughts
 --------------
 
-With the ``ResolveTargetEntityListener``, you are able to decouple your
-modules, keeping them usable by themselves, but still being able to
-define relationships between different objects. By using this method,
-your modules will end up being easier to maintain independently.
+Using ``ResolveTargetEntityListener`` allows you to decouple your modules
+while still defining relationships between their entities. This makes your
+codebase more modular and easier to maintain over time.

From 15728d3dbe8e79d47d0cef98b5c784673ed72619 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 27 May 2025 13:05:49 +0200
Subject: [PATCH 691/747] Minor tweaks

---
 security/access_token.rst | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/security/access_token.rst b/security/access_token.rst
index 0370949e584..4d358aec526 100644
--- a/security/access_token.rst
+++ b/security/access_token.rst
@@ -411,15 +411,15 @@ and retrieve the user info:
             ;
         };
 
-To enable the `OpenID Connect Discovery`_, the ``OidcUserInfoTokenHandler``
+To enable `OpenID Connect Discovery`_, the ``OidcUserInfoTokenHandler``
 requires the ``symfony/cache`` package to store the OIDC configuration in
-cache. If you haven't installed it yet, run this command:
+the cache. If you haven't installed it yet, run the following command:
 
 .. code-block:: terminal
 
     $ composer require symfony/cache
 
-Then, configure the ``base_uri`` and ``discovery`` keys:
+Next, configure the ``base_uri`` and ``discovery`` options:
 
 .. configuration-block::
 
@@ -477,6 +477,10 @@ Then, configure the ``base_uri`` and ``discovery`` keys:
             ;
         };
 
+.. versionadded:: 7.3
+
+    Support for OpenID Connect Discovery was introduced in Symfony 7.3.
+
 Following the `OpenID Connect Specification`_, the ``sub`` claim is used as user
 identifier by default. To use another claim, specify it on the configuration:
 
@@ -691,16 +695,16 @@ it and retrieve the user info from it:
     The support of multiple algorithms to sign the JWS was introduced in Symfony 7.1.
     In previous versions, only the ``ES256`` algorithm was supported.
 
-To enable the `OpenID Connect Discovery`_, the ``OidcTokenHandler``
-requires the ``symfony/cache`` package to store the OIDC configuration in
-cache. If you haven't installed it yet, run this command:
+To enable `OpenID Connect Discovery`_, the ``OidcTokenHandler`` requires the
+``symfony/cache`` package to store the OIDC configuration in the cache. If you
+haven't installed it yet, run the following command:
 
 .. code-block:: terminal
 
     $ composer require symfony/cache
 
-Then, you can remove the ``keyset`` configuration key (it will be imported from
-the OpenID Connect Discovery), and configure the ``discovery`` key:
+Then, you can remove the ``keyset`` configuration option (it will be imported
+from the OpenID Connect Discovery), and configure the ``discovery`` option:
 
 .. configuration-block::
 

From 8b403f7948d9ce2bcec4f63b2783d8a055436a90 Mon Sep 17 00:00:00 2001
From: Florent Morselli <florent.morselli@spomky-labs.com>
Date: Sun, 9 Feb 2025 10:44:02 +0100
Subject: [PATCH 692/747] Add support for encrypted access tokens (JWE) in OIDC

This update introduces support for decrypting encrypted access tokens (JWE) in Symfony 7.3. It includes configuration options for enabling encryption, enforcing it, specifying decryption algorithms, and providing decryption keysets. The feature extends flexibility in handling secure tokens alongside existing signing mechanisms.
---
 security/access_token.rst | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/security/access_token.rst b/security/access_token.rst
index 4d358aec526..70c9e21980e 100644
--- a/security/access_token.rst
+++ b/security/access_token.rst
@@ -615,8 +615,8 @@ If you haven't installed it yet, run this command:
 
     $ composer require web-token/jwt-library
 
-Symfony provides a generic ``OidcTokenHandler`` to decode your token, validate
-it and retrieve the user info from it:
+Symfony provides a generic ``OidcTokenHandler`` that decodes the token, validates
+it, and retrieves the user information from it. Optionally, the token can be encrypted (JWE):
 
 .. configuration-block::
 
@@ -637,6 +637,11 @@ it and retrieve the user info from it:
                                 audience: 'api-example'
                                 # Issuers (`iss` claim): required for validation purpose
                                 issuers: ['https://oidc.example.com']
+                                encryption:
+                                    enabled: true # Default to false
+                                    enforce: false # Default to false, requires an encrypted token when true
+                                    algorithms: ['ECDH-ES', 'A128GCM']
+                                    keyset: '{"keys": [...]}' # Encryption private keyset
 
     .. code-block:: xml
 
@@ -662,6 +667,10 @@ it and retrieve the user info from it:
                                 <algorithm>ES256</algorithm>
                                 <algorithm>RS256</algorithm>
                                 <issuer>https://oidc.example.com</issuer>
+                                <encryption enabled="true" enforce="true" keyset="{'keys': [...]}">
+                                    <algorithm>ECDH-ES</algorithm>
+                                    <algorithm>A128GCM</algorithm>
+                                </encryption>
                             </oidc>
                         </token-handler>
                     </access-token>
@@ -681,12 +690,20 @@ it and retrieve the user info from it:
                         ->oidc()
                             // Algorithm used to sign the JWS
                             ->algorithms(['ES256', 'RS256'])
-                            // A JSON-encoded JWK
+                            // A JSON-encoded JWKSet (public keys)
                             ->keyset('{"keys":[{"kty":"...","k":"..."}]}')
                             // Audience (`aud` claim): required for validation purpose
                             ->audience('api-example')
                             // Issuers (`iss` claim): required for validation purpose
                             ->issuers(['https://oidc.example.com'])
+                            ->encryption()
+                                ->enabled(true) //Default to false
+                                ->enforce(false) //Default to false, requires an encrypted token when true
+                                // Algorithm used to decrypt the JWE
+                                ->algorithms(['ECDH-ES', 'A128GCM'])
+                                // A JSON-encoded JWKSet (private keys)
+                                ->keyset('{"keys":[...]}')
+
             ;
         };
 
@@ -695,6 +712,10 @@ it and retrieve the user info from it:
     The support of multiple algorithms to sign the JWS was introduced in Symfony 7.1.
     In previous versions, only the ``ES256`` algorithm was supported.
 
+.. versionadded:: 7.3
+
+    Support for encryption algorithms to decrypt JWEs was introduced in Symfony 7.3.
+
 To enable `OpenID Connect Discovery`_, the ``OidcTokenHandler`` requires the
 ``symfony/cache`` package to store the OIDC configuration in the cache. If you
 haven't installed it yet, run the following command:

From 22cd58eb815c7c672ab3d4f7164ed8a51dcca7bd Mon Sep 17 00:00:00 2001
From: Mathieu Santostefano <msantostefano@proton.me>
Date: Sun, 9 Feb 2025 17:56:57 +0100
Subject: [PATCH 693/747] [Routing] Add Attribute code examples for alias in
 `#[Route]` attribute

---
 routing.rst | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/routing.rst b/routing.rst
index e634a410c37..2f18b121472 100644
--- a/routing.rst
+++ b/routing.rst
@@ -1340,6 +1340,23 @@ have been renamed. Let's say you have a route called ``product_show``:
 
 .. configuration-block::
 
+    .. code-block:: php-attributes
+
+        // src/Controller/ProductController.php
+        namespace App\Controller;
+
+        use Symfony\Component\HttpFoundation\Response;
+        use Symfony\Component\Routing\Attribute\Route;
+
+        class ProductController
+        {
+            #[Route('/product/{id}', name: 'product_show')]
+            public function show(): Response
+            {
+                // ...
+            }
+        }
+
     .. code-block:: yaml
 
         # config/routes.yaml
@@ -1376,6 +1393,25 @@ Instead of duplicating the original route, you can create an alias for it.
 
 .. configuration-block::
 
+    .. code-block:: php-attributes
+
+        // src/Controller/ProductController.php
+        namespace App\Controller;
+
+        use Symfony\Component\HttpFoundation\Response;
+        use Symfony\Component\Routing\Attribute\Route;
+
+        class ProductController
+        {
+            // "alias" named argument indicates the name of the alias you want to create.
+            // The alias will point to the actual route "product_show"
+            #[Route('/product/{id}', name: 'product_show', alias: ['product_details'])]
+            public function show(): Response
+            {
+                // ...
+            }
+        }
+
     .. code-block:: yaml
 
         # config/routes.yaml
@@ -1416,6 +1452,15 @@ Instead of duplicating the original route, you can create an alias for it.
 In this example, both ``product_show`` and ``product_details`` routes can
 be used in the application and will produce the same result.
 
+.. note::
+
+    Using non-attributes formats (YAML, XML and PHP) is the only way
+    to define an alias pointing to a route that you don't own.
+
+    So that you can use your own route name for URL generation,
+    while actually using a route defined by a third-party bundle as the target of that URL generation,
+    as the 2 definitions are not required to be in the same config file (or even in the same format).
+
 .. _routing-alias-deprecation:
 
 Deprecating Route Aliases
@@ -1436,6 +1481,42 @@ This way, the ``product_show`` alias could be deprecated.
 
 .. configuration-block::
 
+    .. code-block:: php-attributes
+
+        // src/Controller/ProductController.php
+        namespace App\Controller;
+
+        use Symfony\Component\HttpFoundation\Response;
+        use Symfony\Component\Routing\Attribute\Route;
+
+        class ProductController
+        {
+            // this outputs the following generic deprecation message:
+            // Since acme/package 1.2: The "product_show" route alias is deprecated. You should stop using it, as it will be removed in the future.
+            #[Route('/product/{id}',
+                name: 'product_details',
+                alias: new DeprecatedAlias(
+                    aliasName: 'product_show',
+                    package: 'acme/package',
+                    version: '1.2',
+                ),
+            )]
+            // Or, you can also define a custom deprecation message (%alias_id% placeholder is available)
+            #[Route('/product/{id}',
+                name: 'product_details',
+                alias: new DeprecatedAlias(
+                    aliasName: 'product_show',
+                    package: 'acme/package',
+                    version: '1.2',
+                    message: 'The "%alias_id%" route alias is deprecated. Please use "product_details" instead.',
+                ),
+            )]
+            public function show(): Response
+            {
+                // ...
+            }
+        }
+
     .. code-block:: yaml
 
         # Move the concrete route definition under ``product_details``

From 32e93b8b32003bd7bbe123f21137a19d87c5c185 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 27 May 2025 15:33:25 +0200
Subject: [PATCH 694/747] Tweaks and added the versionadded directive

---
 routing.rst | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/routing.rst b/routing.rst
index ee913f07b4c..bf3946b343d 100644
--- a/routing.rst
+++ b/routing.rst
@@ -1405,8 +1405,8 @@ Instead of duplicating the original route, you can create an alias for it.
 
         class ProductController
         {
-            // "alias" named argument indicates the name of the alias you want to create.
-            // The alias will point to the actual route "product_show"
+            // the "alias" argument assigns an alternate name to this route;
+            // the alias will point to the actual route "product_show"
             #[Route('/product/{id}', name: 'product_show', alias: ['product_details'])]
             public function show(): Response
             {
@@ -1451,17 +1451,21 @@ Instead of duplicating the original route, you can create an alias for it.
             $routes->alias('product_details', 'product_show');
         };
 
+.. versionadded:: 7.3
+
+    Support for route aliases in PHP attributes was introduced in Symfony 7.3.
+
 In this example, both ``product_show`` and ``product_details`` routes can
 be used in the application and will produce the same result.
 
 .. note::
 
-    Using non-attributes formats (YAML, XML and PHP) is the only way
-    to define an alias pointing to a route that you don't own.
+    YAML, XML, and PHP configuration formats are the only ways to define an alias
+    for a route that you do not own. You can't do this when using PHP attributes.
 
-    So that you can use your own route name for URL generation,
-    while actually using a route defined by a third-party bundle as the target of that URL generation,
-    as the 2 definitions are not required to be in the same config file (or even in the same format).
+    This allows you for example to use your own route name for URL generation,
+    while still targeting a route defined by a third-party bundle. The alias and
+    the original route do not need to be declared in the same file or format.
 
 .. _routing-alias-deprecation:
 

From c15467e0abef4c60c6e2265994fc5761127f7b2c Mon Sep 17 00:00:00 2001
From: Matthieu Lempereur <matt.lempereur@gmail.com>
Date: Mon, 31 Mar 2025 13:32:59 +0200
Subject: [PATCH 695/747] [Messenger] [Amqp] Add default exchange support

---
 messenger.rst | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index fc8f9491022..f4c3f683627 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1645,11 +1645,15 @@ The transport has a number of options:
     Exchange flags
 
 ``exchange[name]``
-    Name of the exchange
+    Name of the exchange, an empty string can be used to use the default exchange
 
 ``exchange[type]`` (default: ``fanout``)
     Type of exchange
 
+.. versionadded:: 7.3
+
+    Empty string support for ``exchange[name]`` was introduced in Symfony 7.3.
+
 You can also configure AMQP-specific settings on your message by adding
 :class:`Symfony\\Component\\Messenger\\Bridge\\Amqp\\Transport\\AmqpStamp` to
 your Envelope::

From b17f770615cfe7beb1291746bb186cc07c4a8f8e Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 27 May 2025 16:10:17 +0200
Subject: [PATCH 696/747] Minor tweak

---
 messenger.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index 08fdcf7f4dc..46ee188d68d 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -1645,7 +1645,7 @@ The transport has a number of options:
     Exchange flags
 
 ``exchange[name]``
-    Name of the exchange, an empty string can be used to use the default exchange
+    Name of the exchange. Use an empty string to use the default exchange.
 
 ``exchange[type]`` (default: ``fanout``)
     Type of exchange

From 326e7e52585777d299865e5b788b9c00519aabe4 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 27 May 2025 16:45:15 +0200
Subject: [PATCH 697/747] Tweaks and rewords

---
 security/custom_authenticator.rst | 73 +++++++++++++++----------------
 1 file changed, 35 insertions(+), 38 deletions(-)

diff --git a/security/custom_authenticator.rst b/security/custom_authenticator.rst
index 5877194ab4e..ed22ab96d19 100644
--- a/security/custom_authenticator.rst
+++ b/security/custom_authenticator.rst
@@ -219,10 +219,10 @@ identifier (e.g. the username or email)::
 User Identifier
 ~~~~~~~~~~~~~~~
 
-The user identifier is a unique string that identifies the user. It is used
-to load the user using :ref:`the user provider <security-user-providers>`.
-This identifier is often something like the user's email address or username,
-but it could be any unique value associated with the user.
+The user identifier is a unique string that identifies the user. It is often
+something like their email address or username, but it can be any unique value
+associated with the user. It allows loading the user through the configured
+:ref:`user provider <security-user-providers>`.
 
 .. note::
 
@@ -262,21 +262,39 @@ but it could be any unique value associated with the user.
             }
         }
 
-It is a good practice to normalize the user identifier before using it.
-For example, this ensures that variations such as "john.doe", "John.Doe",
-or "JOHN.DOE" refer to the same user.
-Normalization can include converting the identifier to lowercase
-and trimming unnecessary spaces.
-You can optionally pass a user identifier normalizer as third argument to the
-``UserBadge``. This callable receives the ``$userIdentifier``
-and must return a normalized user identifier as a string.
+It's a good practice to normalize the user identifier before using it. This
+ensures that variations like "john.doe", "John.Doe", or "JOHN.DOE" are treated
+as the same user.
+
+Normalization typically involves converting the identifier to lowercase and
+trimming extra spaces. For example, Google considers the following email
+addresses equivalent: ``john.doe@gmail.com``, ``j.hon.d.oe@gmail.com``, and
+``johndoe@gmail.com``. This is due to normalization rules that remove dots and
+lowercase the address.
+
+In enterprise environments, users might authenticate using different identifier
+formats, such as:
+
+* ``john.doe@acme.com``
+* ``acme.com\jdoe``
+* ``https://acme.com/+jdoe``
+* ``acct:jdoe@acme.com``
+
+Applying normalization (e.g. lowercasing, trimming, or unifying formats) helps
+ensure consistent identity resolution and prevents duplication caused by
+format differences.
+
+In Symfony applications, you can optionally pass a user identifier normalizer as
+the third argument to the ``UserBadge``. This callable receives the ``$userIdentifier``
+and must return a normalized string.
 
 .. versionadded:: 7.3
 
-    The support of the user identifier normalizer was introduced in Symfony 7.3.
+    Support for user identifier normalizers was introduced in Symfony 7.3.
 
-For instance, the example below uses a normalizer that converts usernames to a normalized, ASCII-only, lowercase format,
-suitable for consistent comparison and storage.
+For instance, the example below uses a normalizer that converts usernames to
+a normalized, ASCII-only, lowercase format suitable for consistent comparison
+and storage::
 
     // src/Security/NormalizedUserBadge.php
     namespace App\Security;
@@ -319,33 +337,12 @@ suitable for consistent comparison and storage.
         }
     }
 
-.. note::
-
-    For example, Google treats the following email addresses as equivalent:
-    ``john.doe@gmail.com``, ``j.hon.d.oe@gmail.com``, and ``johndoe@gmail.com``.
-    This is because Google applies normalization rules that remove dots
-    and convert the address to lowercase (though behavior varies across services).
-
-.. note::
-
-    In enterprise environments, a user may authenticate using different formats
-    of their identifier, such as:
-
-    - ``john.doe@acme.com``
-    - ``acme.com\jdoe``
-    - ``https://acme.com/+jdoe``
-    - ``acct:jdoe@acme.com``
-
-    Applying normalization (e.g., trimming, lowercasing, or format unification)
-    helps ensure consistent identity recognition across systems and prevents
-    duplicates caused by format variations.
-
 User Credential
 ~~~~~~~~~~~~~~~
 
-The user credential is used to authenticate the user i.e. to verify
+The user credential is used to authenticate the user; that is, to verify
 the validity of the provided information (such as a password, an API token,
-or other custom credentials).
+or custom credentials).
 
 The following credential classes are supported by default:
 

From ece1723cd9f4a3bf908159742444cd8c12ae5971 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 28 May 2025 10:46:47 +0200
Subject: [PATCH 698/747] Fixed a minor RST syntax issue

---
 components/cache/adapters/redis_adapter.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/cache/adapters/redis_adapter.rst b/components/cache/adapters/redis_adapter.rst
index 3362f4cc2db..23dd8d948a1 100644
--- a/components/cache/adapters/redis_adapter.rst
+++ b/components/cache/adapters/redis_adapter.rst
@@ -222,7 +222,7 @@ Available Options
 
 .. versionadded:: 7.1
 
-    The option `sentinel_master` as an alias for `redis_sentinel` was introduced
+    The option ``sentinel_master`` as an alias for ``redis_sentinel`` was introduced
     in Symfony 7.1.
 
 .. note::

From fa9df566b994fe1ee54f851e087f2bdf0a4b30b0 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 29 May 2025 07:54:14 +0200
Subject: [PATCH 699/747] [Security] Fixed a code example

---
 security/custom_authenticator.rst | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/security/custom_authenticator.rst b/security/custom_authenticator.rst
index ed22ab96d19..fd7fa0b139e 100644
--- a/security/custom_authenticator.rst
+++ b/security/custom_authenticator.rst
@@ -300,14 +300,13 @@ and storage::
     namespace App\Security;
 
     use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
-    use Symfony\Component\String\UnicodeString;
     use function Symfony\Component\String\u;
 
     final class NormalizedUserBadge extends UserBadge
     {
         public function __construct(string $identifier)
         {
-            $callback = static fn (string $identifier) => u($identifier)->normalize(UnicodeString::NFKC)->ascii()->lower()->toString();
+            $callback = static fn (string $identifier): string => u($identifier)->normalize(UnicodeString::NFKC)->ascii()->lower()->toString();
 
             parent::__construct($identifier, null, $callback);
         }
@@ -318,7 +317,7 @@ and storage::
 
     final class PasswordAuthenticator extends AbstractLoginFormAuthenticator
     {
-        // Simplified for brievety
+        // simplified for brevity
         public function authenticate(Request $request): Passport
         {
             $username = (string) $request->request->get('username', '');
@@ -331,7 +330,7 @@ and storage::
                 new NormalizedUserBadge($username),
                 new PasswordCredentials($password),
                 [
-                    //All other useful badges
+                    // all other useful badges
                 ]
             );
         }

From d923acb02ff743309fe3b2be2a69c95aee704928 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 28 May 2025 08:43:53 +0200
Subject: [PATCH 700/747] [Security] Document the new `expose_security_errors`
 option

---
 reference/configuration/security.rst | 31 +++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst
index c8609c20c9c..8bae363d9cf 100644
--- a/reference/configuration/security.rst
+++ b/reference/configuration/security.rst
@@ -23,7 +23,8 @@ key in your application configuration.
 
 * `access_denied_url`_
 * `erase_credentials`_
-* `hide_user_not_found`_
+* `expose_security_errors`_
+* `hide_user_not_found`_ (deprecated)
 * `session_fixation_strategy`_
 
 **Advanced Options**:
@@ -71,11 +72,39 @@ after authentication::
    Since Symfony 7.3, ``eraseCredentials()`` methods are deprecated and are
    not called if they have the ``#[\Deprecated]`` attribute.
 
+expose_security_errors
+----------------------
+
+**type**: ``string`` **default**: ``'none'``
+
+.. deprecated:: 7.3
+
+    The ``expose_security_errors`` option was introduced in Symfony 7.3
+
+User enumeration is a common security issue where attackers infer valid usernames
+based on error messages. For example, a message like "This user does not exist"
+shown by your login form reveals whether a username exists.
+
+This option lets you hide some or all errors related to user accounts
+(e.g. blocked or expired accounts) to prevent this issue. Instead, these
+errors will trigger a generic ``BadCredentialsException``. The value of this
+option can be one of the following:
+
+* ``'none'``: hides all user-related security exceptions;
+* ``'account_status'``: shows account-related exceptions (e.g. blocked or expired
+  accounts) but only for users who provided the correct password;
+* ``'all'``: shows all security-related exceptions.
+
 hide_user_not_found
 -------------------
 
 **type**: ``boolean`` **default**: ``true``
 
+.. deprecated:: 7.3
+
+    The ``hide_user_not_found`` option was deprecated in favor of the
+    ``expose_security_errors`` option in Symfony 7.3.
+
 If ``true``, when a user is not found a generic exception of type
 :class:`Symfony\\Component\\Security\\Core\\Exception\\BadCredentialsException`
 is thrown with the message "Bad credentials".

From c1b44e71348da9b97d9a5aac119dfa9dc1507ac9 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 28 May 2025 10:16:02 +0200
Subject: [PATCH 701/747] [Cache][Lock] Add support for `Relay\Cluster` in docs

---
 components/cache/adapters/redis_adapter.rst | 32 +++++++++++++++++++--
 components/lock.rst                         | 10 +++++--
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/components/cache/adapters/redis_adapter.rst b/components/cache/adapters/redis_adapter.rst
index 9f29eae84e7..c0295b487a0 100644
--- a/components/cache/adapters/redis_adapter.rst
+++ b/components/cache/adapters/redis_adapter.rst
@@ -20,9 +20,9 @@ to utilize a cluster of servers to provide redundancy and/or fail-over is also a
 
     **Requirements:** At least one `Redis server`_ must be installed and running to use this
     adapter. Additionally, this adapter requires a compatible extension or library that implements
-    ``\Redis``, ``\RedisArray``, ``RedisCluster``, ``\Relay\Relay`` or ``\Predis``.
+    ``\Redis``, ``\RedisArray``, ``RedisCluster``, ``\Relay\Relay``, ``\Relay\Cluster`` or ``\Predis``.
 
-This adapter expects a `Redis`_, `RedisArray`_, `RedisCluster`_, `Relay`_ or `Predis`_ instance to be
+This adapter expects a `Redis`_, `RedisArray`_, `RedisCluster`_, `Relay`_, `RelayCluster`_ or `Predis`_ instance to be
 passed as the first parameter. A namespace and default cache lifetime can optionally be passed
 as the second and third parameters::
 
@@ -48,6 +48,10 @@ as the second and third parameters::
         ?MarshallerInterface $marshaller = null
     );
 
+.. versionadded:: 7.3
+
+    Support for ``Relay\Cluster`` was introduced in Symfony 7.3.
+
 Configure the Connection
 ------------------------
 
@@ -226,11 +230,34 @@ Available Options
 ``ssl`` (type: ``array``, default: ``null``)
     SSL context options. See `php.net/context.ssl`_ for more information.
 
+``relay_cluster_context`` (type: ``array``, default: ``[]``)
+    Defines configuration options specific to ``\Relay\Cluster``. For example, to
+    user a self-signed certificate for testing in local environment::
+
+        $options = [
+            // ...
+            'relay_cluster_context' => [
+                // ...
+                'stream' => [
+                    'verify_peer' => false,
+                    'verify_peer_name' => false,
+                    'allow_self_signed' => true,
+                    'local_cert' => '/valkey.crt',
+                    'local_pk' => '/valkey.key',
+                    'cafile' => '/valkey.crt',
+                ],
+            ],
+        ];
+
 .. versionadded:: 7.1
 
     The option ``sentinel_master`` as an alias for ``redis_sentinel`` was introduced
     in Symfony 7.1.
 
+.. versionadded:: 7.3
+
+    The ``relay_cluster_context`` option was introduced in Symfony 7.3.
+
 .. note::
 
     When using the `Predis`_ library some additional Predis-specific options are available.
@@ -359,6 +386,7 @@ Supports key rotation, ensuring secure decryption with both old and new keys::
 .. _`RedisArray`: https://github.com/phpredis/phpredis/blob/develop/arrays.md
 .. _`RedisCluster`: https://github.com/phpredis/phpredis/blob/develop/cluster.md
 .. _`Relay`: https://relay.so/
+.. _`RelayCluster`: https://relay.so/docs/1.x/connections#cluster
 .. _`Predis`: https://packagist.org/packages/predis/predis
 .. _`Predis Connection Parameters`: https://github.com/nrk/predis/wiki/Connection-Parameters#list-of-connection-parameters
 .. _`TCP-keepalive`: https://redis.io/topics/clients#tcp-keepalive
diff --git a/components/lock.rst b/components/lock.rst
index b8ba38c8fc7..2403763bd4a 100644
--- a/components/lock.rst
+++ b/components/lock.rst
@@ -612,9 +612,9 @@ RedisStore
 ~~~~~~~~~~
 
 The RedisStore saves locks on a Redis server, it requires a Redis connection
-implementing the ``\Redis``, ``\RedisArray``, ``\RedisCluster``, ``\Relay\Relay`` or
-``\Predis`` classes. This store does not support blocking, and expects a TTL to
-avoid stalled locks::
+implementing the ``\Redis``, ``\RedisArray``, ``\RedisCluster``, ``\Relay\Relay``,
+``\Relay\Cluster`` or ``\Predis`` classes. This store does not support blocking,
+and expects a TTL to avoid stalled locks::
 
     use Symfony\Component\Lock\Store\RedisStore;
 
@@ -623,6 +623,10 @@ avoid stalled locks::
 
     $store = new RedisStore($redis);
 
+.. versionadded:: 7.3
+
+    Support for ``Relay\Cluster`` was introduced in Symfony 7.3.
+
 .. _lock-store-semaphore:
 
 SemaphoreStore

From 9ef310b4f6201f1e43250ab7705a845c6353b5a6 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 29 May 2025 08:35:11 +0200
Subject: [PATCH 702/747] Removed an unneeded versionadded directive

---
 scheduler.rst | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/scheduler.rst b/scheduler.rst
index cec0fe25ede..de2e448f5af 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -864,11 +864,6 @@ code::
 Modifying the Schedule at Runtime
 ---------------------------------
 
-.. versionadded:: 6.4
-
-    Support for modifying the schedule at runtime and recalculating the heap
-    was introduced in Symfony 6.4.
-
 When a recurring message is added to or removed from the schedule,
 the scheduler automatically restarts and recalculates the internal trigger heap.
 This enables dynamic control of scheduled tasks at runtime::

From f6e1f25d940ee3b0df905a7bf2336826f4a41dff Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@open.de>
Date: Fri, 30 May 2025 07:12:22 +0200
Subject: [PATCH 703/747] fix directive

---
 reference/configuration/security.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst
index 8bae363d9cf..ef7247e330e 100644
--- a/reference/configuration/security.rst
+++ b/reference/configuration/security.rst
@@ -77,7 +77,7 @@ expose_security_errors
 
 **type**: ``string`` **default**: ``'none'``
 
-.. deprecated:: 7.3
+.. versionadded:: 7.3
 
     The ``expose_security_errors`` option was introduced in Symfony 7.3
 

From 8f5409ff0cb84bc433d385a5c8834452e262aecd Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 30 May 2025 08:02:24 +0200
Subject: [PATCH 704/747] Fix a code sample with two PHP classes

---
 security/custom_authenticator.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/security/custom_authenticator.rst b/security/custom_authenticator.rst
index fd7fa0b139e..4efe67548a5 100644
--- a/security/custom_authenticator.rst
+++ b/security/custom_authenticator.rst
@@ -312,6 +312,8 @@ and storage::
         }
     }
 
+::
+
     // src/Security/PasswordAuthenticator.php
     namespace App\Security;
 

From b8d4020bffb713f59837cfe771c0354e82397bc0 Mon Sep 17 00:00:00 2001
From: "Julien \"Nayte\" Robic" <36332481+Nayte91@users.noreply.github.com>
Date: Fri, 30 May 2025 10:50:14 +0200
Subject: [PATCH 705/747] fix(typo): form --> from

---
 object_mapper.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/object_mapper.rst b/object_mapper.rst
index 0eed176c67d..625466ffefc 100644
--- a/object_mapper.rst
+++ b/object_mapper.rst
@@ -485,7 +485,7 @@ target class's properties.
 Note that if both the ``source`` and the ``target`` classes define the ``#[Map]``
 attribute, the ``source`` takes precedence.
 
-Consider the following class that stores the data obtained form an external API
+Consider the following class that stores the data obtained from an external API
 that uses snake_case property names::
 
     // src/Api/Payload.php

From 479e0ad197a1ca23292ca6008ebb6807f2c97e2d Mon Sep 17 00:00:00 2001
From: Thomas Landauer <thomas@landauer.at>
Date: Fri, 30 May 2025 17:07:45 +0200
Subject: [PATCH 706/747] [AssetMapper]: "server" -> "machine"

Page: https://symfony.com/doc/current/frontend/asset_mapper.html#pre-compressing-assets

Doesn't have to be a server, can be any (dev) machine, right?
---
 frontend/asset_mapper.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index d9c15a136b0..247f4f60763 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -740,7 +740,7 @@ Symfony will add a ``Link`` header in the response to preload the CSS files.
 Pre-Compressing Assets
 ----------------------
 
-Although most servers (Caddy, Nginx, Apache, FrankenPHP) and services like Cloudflare
+Although most web servers (Caddy, Nginx, Apache, FrankenPHP) and services like Cloudflare
 provide asset compression features, AssetMapper also allows you to compress all
 your assets before serving them.
 
@@ -750,7 +750,7 @@ server, which then returns them to the client without wasting CPU resources on
 compression.
 
 AssetMapper supports  `Brotli`_, `Zstandard`_ and  `gzip`_ compression formats.
-Before using any of them, the server that pre-compresses assets must have
+Before using any of them, the machine that pre-compresses assets must have
 installed the following PHP extensions or CLI commands:
 
 * Brotli: ``brotli`` CLI command; `brotli PHP extension`_;

From 3badfa66e9e014ad1ba4464fdffa0417a440c042 Mon Sep 17 00:00:00 2001
From: Thomas Landauer <thomas@landauer.at>
Date: Fri, 30 May 2025 18:09:03 +0200
Subject: [PATCH 707/747] [AssetMapper]: Adding possible precompressor values

Page: https://symfony.com/doc/current/frontend/asset_mapper.html#pre-compressing-assets

Info is taken from: https://symfony.com/blog/new-in-symfony-7-3-assets-pre-compression
---
 frontend/asset_mapper.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index d9c15a136b0..e3525c9b18c 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -768,6 +768,7 @@ and which file extensions should be compressed:
             # ...
 
             precompress:
+                # possible values: 'brotli', 'zstandard', 'gzip'
                 format: 'zstandard'
                 # if you don't define the following option, AssetMapper will compress all
                 # the extensions considered safe (css, js, json, svg, xml, ttf, otf, wasm, etc.)

From dfb08eb2d20bd5ab7207db000660a60d36428c44 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 2 Jun 2025 10:44:52 +0200
Subject: [PATCH 708/747] [AssetMapper] Added the missing versionadded
 directive

---
 frontend/asset_mapper.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index 247f4f60763..7e566204193 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -740,6 +740,10 @@ Symfony will add a ``Link`` header in the response to preload the CSS files.
 Pre-Compressing Assets
 ----------------------
 
+.. versionadded:: 7.3
+
+    Support for pre-compressing assets was introduced in Symfony 7.3.
+
 Although most web servers (Caddy, Nginx, Apache, FrankenPHP) and services like Cloudflare
 provide asset compression features, AssetMapper also allows you to compress all
 your assets before serving them.

From 70f206764bba5d5cdac2eb61dd0cd47dfff75f2e Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 3 Jun 2025 12:13:42 +0200
Subject: [PATCH 709/747] Minor tweaks

---
 frontend/asset_mapper.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/frontend/asset_mapper.rst b/frontend/asset_mapper.rst
index d88d4ac258e..454e13a1d29 100644
--- a/frontend/asset_mapper.rst
+++ b/frontend/asset_mapper.rst
@@ -774,6 +774,10 @@ and which file extensions should be compressed:
             precompress:
                 # possible values: 'brotli', 'zstandard', 'gzip'
                 format: 'zstandard'
+
+                # you can also pass multiple values to generate files in several formats
+                # format: ['brotli', 'zstandard']
+
                 # if you don't define the following option, AssetMapper will compress all
                 # the extensions considered safe (css, js, json, svg, xml, ttf, otf, wasm, etc.)
                 extensions: ['css', 'js', 'json', 'svg', 'xml']

From f3c8163f2751ab06836f24c83f6b8d70df2b0257 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Wed, 4 Jun 2025 23:07:19 +0200
Subject: [PATCH 710/747] minor

---
 lock.rst                              | 2 +-
 reference/configuration/framework.rst | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lock.rst b/lock.rst
index d9d57481f3d..6bfe7a5390e 100644
--- a/lock.rst
+++ b/lock.rst
@@ -135,8 +135,8 @@ this behavior by using the ``lock`` key like:
     .. code-block:: php
 
         // config/packages/lock.php
-        use function Symfony\Component\DependencyInjection\Loader\Configurator\env;
         use Symfony\Config\FrameworkConfig;
+        use function Symfony\Component\DependencyInjection\Loader\Configurator\env;
 
         return static function (FrameworkConfig $framework): void {
             $framework->lock()
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index d30b8e3879c..26e36b264fe 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -2811,8 +2811,8 @@ the name as key and DSN or service id as value:
     .. code-block:: php
 
         // config/packages/semaphore.php
-        use function Symfony\Component\DependencyInjection\Loader\Configurator\env;
         use Symfony\Config\FrameworkConfig;
+        use function Symfony\Component\DependencyInjection\Loader\Configurator\env;
 
         return static function (FrameworkConfig $framework): void {
             $framework->semaphore()

From 6f6566daa3a06c474f965792a5d6fa9f8c728f82 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 4 Jun 2025 15:21:19 +0200
Subject: [PATCH 711/747] [Validation] Add the `disable_translation` option

---
 reference/configuration/framework.rst | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index ad2b7587e5f..e37e28f6caf 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -3660,6 +3660,22 @@ Defines the Doctrine entities that will be introspected to add
                     ]);
         };
 
+.. _reference-validation-disable_translation:
+
+disable_translation
+...................
+
+**type**: ``boolean`` **default**: ``false``
+
+Validation error messages are automatically translated to the current application
+locale. Set this option to ``true`` to disable translation of validation messages.
+This is useful to avoid "missing translation" errors in applications that use
+only a single language.
+
+.. versionadded:: 7.3
+
+    The ``disable_translation`` option was introduced in Symfony 7.3.
+
 .. _reference-validation-email_validation_mode:
 
 email_validation_mode

From 9b0e108449a2a2e8368d88806b58e9f6a8a57790 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 5 Jun 2025 08:13:20 +0200
Subject: [PATCH 712/747] Add a reference to a config option

---
 validation/custom_constraint.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/validation/custom_constraint.rst b/validation/custom_constraint.rst
index 031e37b79b2..1996c64e3ca 100644
--- a/validation/custom_constraint.rst
+++ b/validation/custom_constraint.rst
@@ -181,6 +181,7 @@ The ``addViolation()`` method call finally adds the violation to the context.
     Validation error messages are automatically translated to the current application
     locale. If your application doesn't use translations, you can disable this behavior
     by calling the ``disableTranslation()`` method of ``ConstraintViolationBuilderInterface``.
+    See also the :ref:`framework.validation.disable_translation option <reference-validation-disable_translation>`.
 
     .. versionadded:: 6.4
 

From 271313b99ef6ab080d166287a14acf5286e43871 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 5 Jun 2025 08:13:54 +0200
Subject: [PATCH 713/747] Remove a versionadded directive

---
 validation/custom_constraint.rst | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/validation/custom_constraint.rst b/validation/custom_constraint.rst
index 665bc361dc4..6af3097a829 100644
--- a/validation/custom_constraint.rst
+++ b/validation/custom_constraint.rst
@@ -182,10 +182,6 @@ The ``addViolation()`` method call finally adds the violation to the context.
     locale. If your application doesn't use translations, you can disable this behavior
     by calling the ``disableTranslation()`` method of ``ConstraintViolationBuilderInterface``.
 
-    .. versionadded:: 6.4
-
-        The ``disableTranslation()`` method was introduced in Symfony 6.4.
-
 Using the new Validator
 -----------------------
 

From 5edccbfa808a98cc9801d90ef19cd3e64dbf3fdc Mon Sep 17 00:00:00 2001
From: Ian Kevin Irlen <kvinirlen@gmail.com>
Date: Thu, 12 Jun 2025 14:19:43 +0400
Subject: [PATCH 714/747] Update custom_normalizer.rst

---
 serializer/custom_normalizer.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/serializer/custom_normalizer.rst b/serializer/custom_normalizer.rst
index 9c037f7f33c..4e78d9d394e 100644
--- a/serializer/custom_normalizer.rst
+++ b/serializer/custom_normalizer.rst
@@ -38,14 +38,14 @@ normalization process::
 
         public function normalize(mixed $data, ?string $format = null, array $context = []): array
         {
-            $data = $this->normalizer->normalize($data, $format, $context);
+            $normalizedData = $this->normalizer->normalize($data, $format, $context);
 
             // Here, add, edit, or delete some data:
-            $data['href']['self'] = $this->router->generate('topic_show', [
-                'id' => $object->getId(),
+            $normalizedData['href']['self'] = $this->router->generate('topic_show', [
+                'id' => $data->getId(),
             ], UrlGeneratorInterface::ABSOLUTE_URL);
 
-            return $data;
+            return $normalizedData;
         }
 
         public function supportsNormalization($data, ?string $format = null, array $context = []): bool

From 432f468059889548545b4959ade7473715628c16 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=93=D1=80=D0=B8=D0=B3=D0=BE=D1=80=D0=B8=D0=B9?=
 <grin180898@mail.ru>
Date: Sun, 15 Jun 2025 19:37:58 +0300
Subject: [PATCH 715/747] Update tree.rst

fix($ sign before the variable)
---
 components/console/helpers/tree.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/console/helpers/tree.rst b/components/console/helpers/tree.rst
index b5839b74a26..0839fb943e2 100644
--- a/components/console/helpers/tree.rst
+++ b/components/console/helpers/tree.rst
@@ -115,7 +115,7 @@ class and adding nodes to it::
     $testsNode = new TreeNode('tests/');
     $functionalTestsNode = new TreeNode('Functional/');
     $testsNode->addChild($functionalTestsNode);
-    $root->addChild(testsNode);
+    $root->addChild($testsNode);
 
     $tree = TreeHelper::createTree($io, $root);
     $tree->render();

From abc2df67c5e74731eebbd975e178600c30982112 Mon Sep 17 00:00:00 2001
From: Vincent Amstoutz <vincent.amstoutz@outlook.com>
Date: Thu, 12 Jun 2025 16:59:06 +0200
Subject: [PATCH 716/747] docs(json-path): initiate doc for the component

---
 components/json_path.rst | 246 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 246 insertions(+)
 create mode 100644 components/json_path.rst

diff --git a/components/json_path.rst b/components/json_path.rst
new file mode 100644
index 00000000000..bd0f7c72dcf
--- /dev/null
+++ b/components/json_path.rst
@@ -0,0 +1,246 @@
+The JsonPath Component
+======================
+
+.. versionadded:: 7.3
+
+    The JsonPath component was introduced in Symfony 7.3 as an
+    :doc:`experimental feature </contributing/code/experimental>`.
+
+The JsonPath component provides a powerful way to query and extract data from
+JSON structures. It implements the `RFC 9535 - JSONPath`_
+standard, allowing you to navigate complex JSON data with ease.
+
+Just as the :doc:`DomCrawler component </components/dom_crawler>` allows you to navigate and query HTML/XML documents
+using XPath, the JsonPath component provides a similar experience to traverse and search JSON structures
+using JSONPath expressions. The component also offers an abstraction layer for data extraction.
+
+Installation
+------------
+
+You can install the component in your project using Composer:
+
+.. code-block:: terminal
+
+    $ composer require symfony/json-path
+
+.. include:: /components/require_autoload.rst.inc
+
+Usage
+-----
+
+To start querying a JSON document, first create a :class:`Symfony\\Component\\JsonPath\\JsonCrawler`
+object from a JSON string. For the following examples, we'll use this sample
+"bookstore" JSON data::
+
+    use Symfony\Component\JsonPath\JsonCrawler;
+
+    $json = <<<'JSON'
+    {
+        "store": {
+            "book": [
+                {
+                    "category": "reference",
+                    "author": "Nigel Rees",
+                    "title": "Sayings of the Century",
+                    "price": 8.95
+                },
+                {
+                    "category": "fiction",
+                    "author": "Evelyn Waugh",
+                    "title": "Sword of Honour",
+                    "price": 12.99
+                },
+                {
+                    "category": "fiction",
+                    "author": "Herman Melville",
+                    "title": "Moby Dick",
+                    "isbn": "0-553-21311-3",
+                    "price": 8.99
+                },
+                {
+                    "category": "fiction",
+                    "author": "John Ronald Reuel Tolkien",
+                    "title": "The Lord of the Rings",
+                    "isbn": "0-395-19395-8",
+                    "price": 22.99
+                }
+            ],
+            "bicycle": {
+                "color": "red",
+                "price": 399
+            }
+        }
+    }
+    JSON;
+
+    $crawler = new JsonCrawler($json);
+
+Once you have the crawler instance, use its :method:`Symfony\\Component\\JsonPath\\JsonCrawler::find` method to start querying
+the data. This method always returns an array of matching values.
+
+Querying with Expressions
+-------------------------
+
+The primary way to query the JSON is by passing a JSONPath expression string
+to the :method:`Symfony\\Component\\JsonPath\\JsonCrawler::find` method.
+
+Accessing a Specific Property
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use dot-notation for object keys and square brackets for array indices. The root
+of the document is represented by ``$``::
+
+    // Get the title of the first book in the store
+    $titles = $crawler->find('$.store.book[0].title');
+
+    // $titles is ['Sayings of the Century']
+
+While dot-notation is common, JSONPath offers alternative syntaxes which can be more flexible. For instance, bracket notation (`['...']`) is required if a key contains spaces or special characters::
+
+    // This is equivalent to the previous example and works with special keys
+    $titles = $crawler->find('$["store"]["book"][0]["title"]');
+
+    // You can also build the query programmatically for more complex scenarios
+    use Symfony\Component\JsonPath\JsonPath;
+
+    $path = (new JsonPath())->key('store')->key('book')->first()->key('title');
+    $titles = $crawler->find($path);
+
+Searching with the Descendant Operator
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The descendant operator (``..``) recursively searches for a given key, allowing
+you to find values without specifying the full path::
+
+    // Get all authors from anywhere in the document
+    $authors = $crawler->find('$..author');
+
+    // $authors is ['Nigel Rees', 'Evelyn Waugh', 'Herman Melville', 'John Ronald Reuel Tolkien']
+
+Filtering Results
+~~~~~~~~~~~~~~~~~
+
+JSONPath includes a powerful filter syntax (``?(<expression>)``) to select items
+based on a condition. The current item within the filter is referenced by ``@``::
+
+    // Get all books with a price less than 10
+    $cheapBooks = $crawler->find('$.store.book[?(@.price < 10)]');
+
+    /*
+    $cheapBooks contains two book objects:
+    the one by "Nigel Rees" and the one by "Herman Melville"
+    */
+
+Building Queries Programmatically
+---------------------------------
+
+For more dynamic or complex query building, you can use the fluent API provided
+by the :class:`Symfony\\Component\\JsonPath\\JsonPath` class. This allows you
+to construct a query object step-by-step. The ``JsonPath`` object can then be
+passed to the crawler's :method:`Symfony\\Component\\JsonPath\\JsonCrawler::find` method.
+
+The main advantage of the programmatic builder is that it automatically handles
+the correct escaping of keys and values, preventing syntax errors::
+
+    use Symfony\Component\JsonPath\JsonPath;
+
+    $path = (new JsonPath())
+        ->key('store')       // Selects the 'store' key
+        ->key('book')        // Then the 'book' key
+        ->index(1);          // Then the item at index 1 (the second book)
+
+    // The created $path object is equivalent to the string '$["store"]["book"][1]'
+    $book = $crawler->find($path);
+
+    // $book contains the book object for "Sword of Honour"
+
+The :class:`Symfony\\Component\\JsonPath\\JsonPath` class provides several methods to build your query:
+
+* :method:`Symfony\\Component\\JsonPath\\JsonPath::key`
+    Adds a key selector. The key name will be properly escaped::
+
+        // Creates the path '$["key\"with\"quotes"]'
+        $path = (new JsonPath())->key('key"with"quotes');
+
+* :method:`Symfony\\Component\\JsonPath\\JsonPath::deepScan`
+    Adds the descendant operator ``..`` to perform a recursive search from the
+    current point in the path::
+
+        // Get all prices in the store: '$["store"]..["price"]'
+        $path = (new JsonPath())->key('store')->deepScan()->key('price');
+
+* :method:`Symfony\\Component\\JsonPath\\JsonPath::all`
+    Adds the wildcard operator ``[*]`` to select all items in an array or object::
+
+        // Creates the path '$["store"]["book"][*]'
+        $path = (new JsonPath())->key('store')->key('book')->all();
+
+* :method:`Symfony\\Component\\JsonPath\\JsonPath::index`
+    Adds an array index selector.
+
+* :method:`Symfony\\Component\\JsonPath\\JsonPath::first` / :method:`Symfony\\Component\\JsonPath\\JsonPath::last`
+    Shortcuts for ``index(0)`` and ``index(-1)`` respectively::
+
+        // Get the last book: '$["store"]["book"][-1]'
+        $path = (new JsonPath())->key('store')->key('book')->last();
+
+* :method:`Symfony\\Component\\JsonPath\\JsonPath::slice`
+    Adds an array slice selector ``[start:end:step]``::
+
+        // Get books from index 1 up to (but not including) index 3
+        // Creates the path '$["store"]["book"][1:3]'
+        $path = (new JsonPath())->key('store')->key('book')->slice(1, 3);
+
+        // Get every second book from the first four books
+        // Creates the path '$["store"]["book"][0:4:2]'
+        $path = (new JsonPath())->key('store')->key('book')->slice(0, 4, 2);
+
+* :method:`Symfony\\Component\\JsonPath\\JsonPath::filter`
+    Adds a filter expression. The expression string is the part that goes inside
+    the ``?()`` syntax::
+
+        // Get expensive books: '$["store"]["book"][?(@.price > 20)]'
+        $path = (new JsonPath())
+            ->key('store')
+            ->key('book')
+            ->filter('@.price > 20');
+
+Advanced Querying
+-----------------
+
+For a complete overview of advanced operators like wildcards and functions within
+filters, please refer to the `Querying with Expressions`_ section above. All these
+features are supported and can be combined with the programmatic builder where
+appropriate (e.g., inside a ``filter()`` expression).
+
+Error Handling
+--------------
+
+The component will throw specific exceptions for invalid input or queries:
+
+* :class:`Symfony\\Component\\JsonPath\\Exception\\InvalidArgumentException`: Thrown if the input to the ``JsonCrawler`` constructor is not a valid JSON string.
+* :class:`Symfony\\Component\\JsonPath\\Exception\\InvalidJsonStringInputException`: Thrown during a ``find()`` call if the JSON string is malformed (e.g., syntax error).
+* :class:`Symfony\\Component\\JsonPath\\Exception\\JsonCrawlerException`: Thrown for errors within the JsonPath expression itself, such as using an unknown function::
+
+    use Symfony\Component\JsonPath\Exception\InvalidJsonStringInputException;
+    use Symfony\Component\JsonPath\Exception\JsonCrawlerException;
+
+    try {
+        // Example of malformed JSON
+        $crawler = new JsonCrawler('{"store": }');
+        $crawler->find('$..*');
+    } catch (InvalidJsonStringInputException $e) {
+        // ... handle error
+    }
+
+    try {
+        // Example of an invalid query
+        $crawler->find('$.store.book[?unknown_function(@.price)]');
+    } catch (JsonCrawlerException $e) {
+        // ... handle error
+    }
+
+Learn more
+----------
+
+.. _`RFC 9535 - JSONPath`: https://datatracker.ietf.org/doc/html/rfc9535

From 59b34b4a19ffe4fe138450e7610033ef51f89e24 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Mon, 16 Jun 2025 18:17:54 +0200
Subject: [PATCH 717/747] minor

---
 components/json_path.rst | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/components/json_path.rst b/components/json_path.rst
index bd0f7c72dcf..f4a5f8a2d7d 100644
--- a/components/json_path.rst
+++ b/components/json_path.rst
@@ -240,7 +240,4 @@ The component will throw specific exceptions for invalid input or queries:
         // ... handle error
     }
 
-Learn more
-----------
-
 .. _`RFC 9535 - JSONPath`: https://datatracker.ietf.org/doc/html/rfc9535

From b6bbd96745833faef10337f647d2e3df798f5278 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Mon, 16 Jun 2025 18:22:04 +0200
Subject: [PATCH 718/747] minor

---
 doctrine.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/doctrine.rst b/doctrine.rst
index e14e4b9e4b5..6a1438322fa 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -797,9 +797,9 @@ variable. Let's say you want the first or the last comment of a product dependin
         Comment $comment
     ): Response {
     }
-    
+
 .. _doctrine-entity-value-resolver-resolve-target-entities:
-    
+
 Fetch via Interfaces
 ~~~~~~~~~~~~~~~~~~~~
 
@@ -818,7 +818,7 @@ resolved automatically::
     ): Response {
         // ...
     }
-        
+
 .. versionadded:: 7.3
 
     Support for target entity resolution in the ``EntityValueResolver`` was

From 26defdfc2105699b2e91a9792385fd44f8b8f10a Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Mon, 16 Jun 2025 18:24:30 +0200
Subject: [PATCH 719/747] minor

---
 service_container/tags.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/service_container/tags.rst b/service_container/tags.rst
index fab25ea910a..bc3d28c90ff 100644
--- a/service_container/tags.rst
+++ b/service_container/tags.rst
@@ -162,7 +162,7 @@ class, call this method in the ``loadExtension()`` method of the main bundle cla
     use Symfony\Component\DependencyInjection\ContainerBuilder;
     use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
     use Symfony\Component\HttpKernel\Bundle\AbstractBundle;
-    
+
     class MyBundle extends AbstractBundle
     {
         public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void

From d4c4f2dd5aad66314d56cbd008b68627b216d29a Mon Sep 17 00:00:00 2001
From: Thomas Landauer <thomas@landauer.at>
Date: Mon, 16 Jun 2025 21:46:46 +0200
Subject: [PATCH 720/747] [Security]: Removing recommendations to lowercase
 email adresses

Closes https://github.com/symfony/symfony-docs/issues/21080

Page: https://symfony.com/doc/current/security/custom_authenticator.html#user-identifier
---
 security/custom_authenticator.rst | 34 ++++++-------------------------
 1 file changed, 6 insertions(+), 28 deletions(-)

diff --git a/security/custom_authenticator.rst b/security/custom_authenticator.rst
index d3dab39c719..035054d0899 100644
--- a/security/custom_authenticator.rst
+++ b/security/custom_authenticator.rst
@@ -282,39 +282,17 @@ associated with the user. It allows loading the user through the configured
             }
         }
 
-It's a good practice to normalize the user identifier before using it. This
-ensures that variations like "john.doe", "John.Doe", or "JOHN.DOE" are treated
-as the same user.
-
-Normalization typically involves converting the identifier to lowercase and
-trimming extra spaces. For example, Google considers the following email
-addresses equivalent: ``john.doe@gmail.com``, ``j.hon.d.oe@gmail.com``, and
-``johndoe@gmail.com``. This is due to normalization rules that remove dots and
-lowercase the address.
-
-In enterprise environments, users might authenticate using different identifier
-formats, such as:
-
-* ``john.doe@acme.com``
-* ``acme.com\jdoe``
-* ``https://acme.com/+jdoe``
-* ``acct:jdoe@acme.com``
-
-Applying normalization (e.g. lowercasing, trimming, or unifying formats) helps
-ensure consistent identity resolution and prevents duplication caused by
-format differences.
-
-In Symfony applications, you can optionally pass a user identifier normalizer as
-the third argument to the ``UserBadge``. This callable receives the ``$userIdentifier``
-and must return a normalized string.
+You can normalize the user identifier before using it (e.g. to ensure that variations like
+"john.doe", "John.Doe", or "JOHN.DOE" are treated as the same user).
+In Symfony applications, you can optionally pass a user identifier normalizer as the
+third argument to the ``UserBadge``. This callable receives the ``$userIdentifier`` and must return a string.
 
 .. versionadded:: 7.3
 
     Support for user identifier normalizers was introduced in Symfony 7.3.
 
-For instance, the example below uses a normalizer that converts usernames to
-a normalized, ASCII-only, lowercase format suitable for consistent comparison
-and storage::
+The example below uses a normalizer that converts usernames to
+a normalized, ASCII-only, lowercase format::
 
     // src/Security/NormalizedUserBadge.php
     namespace App\Security;

From 287d274224af825b45cbd699b3f73f7717a23685 Mon Sep 17 00:00:00 2001
From: eltharin <eltharin18@hotmail.fr>
Date: Tue, 17 Jun 2025 08:34:18 +0200
Subject: [PATCH 721/747] repair codeblock

---
 service_container/tags.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/service_container/tags.rst b/service_container/tags.rst
index 7a031c886e7..3a547042de7 100644
--- a/service_container/tags.rst
+++ b/service_container/tags.rst
@@ -1290,7 +1290,7 @@ be used directly on the class of the service you want to configure::
     }
 
 You can apply the ``#[AsTaggedItem]`` attribute multiple times to register the
-same service under different indexes:
+same service under different indexes::
 
     #[AsTaggedItem(index: 'handler_one', priority: 5)]
     #[AsTaggedItem(index: 'handler_two', priority: 20)]

From 974e9d1955428042ca48ed01f116c557152bfc34 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 17 Jun 2025 17:58:59 +0200
Subject: [PATCH 722/747] Minor tweaks

---
 security/custom_authenticator.rst | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/security/custom_authenticator.rst b/security/custom_authenticator.rst
index 035054d0899..462ec21521c 100644
--- a/security/custom_authenticator.rst
+++ b/security/custom_authenticator.rst
@@ -282,17 +282,19 @@ associated with the user. It allows loading the user through the configured
             }
         }
 
-You can normalize the user identifier before using it (e.g. to ensure that variations like
-"john.doe", "John.Doe", or "JOHN.DOE" are treated as the same user).
-In Symfony applications, you can optionally pass a user identifier normalizer as the
-third argument to the ``UserBadge``. This callable receives the ``$userIdentifier`` and must return a string.
+Some applications normalize user identifiers before processing them. For example,
+lowercasing identifiers helps treat values like "john.doe", "John.Doe", or
+"JOHN.DOE" as equivalent in systems where identifiers are case-insensitive.
+
+If needed, you can pass a normalizer as the third argument to ``UserBadge``.
+This callable receives the ``$userIdentifier`` and must return a string.
 
 .. versionadded:: 7.3
 
     Support for user identifier normalizers was introduced in Symfony 7.3.
 
-The example below uses a normalizer that converts usernames to
-a normalized, ASCII-only, lowercase format::
+The example below uses a normalizer that converts usernames to a normalized,
+ASCII-only, lowercase format::
 
     // src/Security/NormalizedUserBadge.php
     namespace App\Security;

From f547cc7ba7149c8355104257810c7292ceadcfb5 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 18 Jun 2025 15:38:58 +0200
Subject: [PATCH 723/747] [JsonPath] Minor fixes and tweaks

---
 components/json_path.rst | 151 ++++++++++++++++++++-------------------
 1 file changed, 78 insertions(+), 73 deletions(-)

diff --git a/components/json_path.rst b/components/json_path.rst
index f4a5f8a2d7d..ec5db0e8e74 100644
--- a/components/json_path.rst
+++ b/components/json_path.rst
@@ -6,13 +6,15 @@ The JsonPath Component
     The JsonPath component was introduced in Symfony 7.3 as an
     :doc:`experimental feature </contributing/code/experimental>`.
 
-The JsonPath component provides a powerful way to query and extract data from
-JSON structures. It implements the `RFC 9535 - JSONPath`_
-standard, allowing you to navigate complex JSON data with ease.
+The JsonPath component lets you query and extract data from JSON structures.
+It implements the `RFC 9535 – JSONPath`_ standard, allowing you to navigate
+complex JSON data.
 
-Just as the :doc:`DomCrawler component </components/dom_crawler>` allows you to navigate and query HTML/XML documents
-using XPath, the JsonPath component provides a similar experience to traverse and search JSON structures
-using JSONPath expressions. The component also offers an abstraction layer for data extraction.
+Similar to the :doc:`DomCrawler component </components/dom_crawler>`, which lets
+you navigate and query HTML or XML documents with XPath, the JsonPath component
+offers the same convenience for traversing and searching JSON structures through
+JSONPath expressions. The component also provides an abstraction layer for data
+extraction.
 
 Installation
 ------------
@@ -29,8 +31,8 @@ Usage
 -----
 
 To start querying a JSON document, first create a :class:`Symfony\\Component\\JsonPath\\JsonCrawler`
-object from a JSON string. For the following examples, we'll use this sample
-"bookstore" JSON data::
+object from a JSON string. The following examples use this sample "bookstore"
+JSON data::
 
     use Symfony\Component\JsonPath\JsonCrawler;
 
@@ -75,8 +77,8 @@ object from a JSON string. For the following examples, we'll use this sample
 
     $crawler = new JsonCrawler($json);
 
-Once you have the crawler instance, use its :method:`Symfony\\Component\\JsonPath\\JsonCrawler::find` method to start querying
-the data. This method always returns an array of matching values.
+Once you have the crawler instance, use its :method:`Symfony\\Component\\JsonPath\\JsonCrawler::find`
+method to start querying the data. This method returns an array of matching values.
 
 Querying with Expressions
 -------------------------
@@ -87,24 +89,26 @@ to the :method:`Symfony\\Component\\JsonPath\\JsonCrawler::find` method.
 Accessing a Specific Property
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Use dot-notation for object keys and square brackets for array indices. The root
+Use dot notation for object keys and square brackets for array indices. The root
 of the document is represented by ``$``::
 
-    // Get the title of the first book in the store
+    // get the title of the first book in the store
     $titles = $crawler->find('$.store.book[0].title');
 
     // $titles is ['Sayings of the Century']
 
-While dot-notation is common, JSONPath offers alternative syntaxes which can be more flexible. For instance, bracket notation (`['...']`) is required if a key contains spaces or special characters::
+Dot notation is the default, but JSONPath provides other syntaxes for cases where
+it doesn't work. Use bracket notation (``['...']``) when a key contains spaces
+or special characters::
 
-    // This is equivalent to the previous example and works with special keys
+    // this is equivalent to the previous example
     $titles = $crawler->find('$["store"]["book"][0]["title"]');
 
-    // You can also build the query programmatically for more complex scenarios
-    use Symfony\Component\JsonPath\JsonPath;
+    // this expression requires brackets because some keys use dots or spaces
+    $titles = $crawler->find('$["store"]["book collection"][0]["title.original"]');
 
-    $path = (new JsonPath())->key('store')->key('book')->first()->key('title');
-    $titles = $crawler->find($path);
+    // you can combine both notations
+    $titles = $crawler->find('$["store"].book[0].title');
 
 Searching with the Descendant Operator
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -112,7 +116,7 @@ Searching with the Descendant Operator
 The descendant operator (``..``) recursively searches for a given key, allowing
 you to find values without specifying the full path::
 
-    // Get all authors from anywhere in the document
+    // get all authors from anywhere in the document
     $authors = $crawler->find('$..author');
 
     // $authors is ['Nigel Rees', 'Evelyn Waugh', 'Herman Melville', 'John Ronald Reuel Tolkien']
@@ -120,113 +124,114 @@ you to find values without specifying the full path::
 Filtering Results
 ~~~~~~~~~~~~~~~~~
 
-JSONPath includes a powerful filter syntax (``?(<expression>)``) to select items
-based on a condition. The current item within the filter is referenced by ``@``::
+JSONPath includes a filter syntax (``?(expression)``) to select items based on
+a condition. The current item within the filter is referenced by ``@``::
 
-    // Get all books with a price less than 10
+    // get all books with a price less than 10
     $cheapBooks = $crawler->find('$.store.book[?(@.price < 10)]');
 
-    /*
-    $cheapBooks contains two book objects:
-    the one by "Nigel Rees" and the one by "Herman Melville"
-    */
-
 Building Queries Programmatically
 ---------------------------------
 
-For more dynamic or complex query building, you can use the fluent API provided
-by the :class:`Symfony\\Component\\JsonPath\\JsonPath` class. This allows you
-to construct a query object step-by-step. The ``JsonPath`` object can then be
-passed to the crawler's :method:`Symfony\\Component\\JsonPath\\JsonCrawler::find` method.
+For more dynamic or complex query building, use the fluent API provided
+by the :class:`Symfony\\Component\\JsonPath\\JsonPath` class. This lets you
+construct a query object step by step. The ``JsonPath`` object can then be passed
+to the crawler's :method:`Symfony\\Component\\JsonPath\\JsonCrawler::find` method.
 
 The main advantage of the programmatic builder is that it automatically handles
-the correct escaping of keys and values, preventing syntax errors::
+escaping of keys and values, preventing syntax errors::
 
     use Symfony\Component\JsonPath\JsonPath;
 
     $path = (new JsonPath())
-        ->key('store')       // Selects the 'store' key
-        ->key('book')        // Then the 'book' key
-        ->index(1);          // Then the item at index 1 (the second book)
+        ->key('store') // selects the 'store' key
+        ->key('book')  // then the 'book' key
+        ->index(1);    // then the second item (indexes start at 0)
 
-    // The created $path object is equivalent to the string '$["store"]["book"][1]'
+    // the created $path object is equivalent to the string '$["store"]["book"][1]'
     $book = $crawler->find($path);
 
     // $book contains the book object for "Sword of Honour"
 
-The :class:`Symfony\\Component\\JsonPath\\JsonPath` class provides several methods to build your query:
+The :class:`Symfony\\Component\\JsonPath\\JsonPath` class provides several
+methods to build your query:
 
 * :method:`Symfony\\Component\\JsonPath\\JsonPath::key`
-    Adds a key selector. The key name will be properly escaped::
+  Adds a key selector. The key name is properly escaped::
 
-        // Creates the path '$["key\"with\"quotes"]'
-        $path = (new JsonPath())->key('key"with"quotes');
+      // creates the path '$["key\"with\"quotes"]'
+      $path = (new JsonPath())->key('key"with"quotes');
 
 * :method:`Symfony\\Component\\JsonPath\\JsonPath::deepScan`
-    Adds the descendant operator ``..`` to perform a recursive search from the
-    current point in the path::
+  Adds the descendant operator ``..`` to perform a recursive search from the
+  current point in the path::
 
-        // Get all prices in the store: '$["store"]..["price"]'
-        $path = (new JsonPath())->key('store')->deepScan()->key('price');
+      // get all prices in the store: '$["store"]..["price"]'
+      $path = (new JsonPath())->key('store')->deepScan()->key('price');
 
 * :method:`Symfony\\Component\\JsonPath\\JsonPath::all`
-    Adds the wildcard operator ``[*]`` to select all items in an array or object::
+  Adds the wildcard operator ``[*]`` to select all items in an array or object::
 
-        // Creates the path '$["store"]["book"][*]'
+        // creates the path '$["store"]["book"][*]'
         $path = (new JsonPath())->key('store')->key('book')->all();
 
 * :method:`Symfony\\Component\\JsonPath\\JsonPath::index`
-    Adds an array index selector.
+  Adds an array index selector. Index numbers start at ``0``.
 
 * :method:`Symfony\\Component\\JsonPath\\JsonPath::first` / :method:`Symfony\\Component\\JsonPath\\JsonPath::last`
-    Shortcuts for ``index(0)`` and ``index(-1)`` respectively::
+  Shortcuts for ``index(0)`` and ``index(-1)`` respectively::
 
-        // Get the last book: '$["store"]["book"][-1]'
-        $path = (new JsonPath())->key('store')->key('book')->last();
+      // get the last book: '$["store"]["book"][-1]'
+      $path = (new JsonPath())->key('store')->key('book')->last();
 
 * :method:`Symfony\\Component\\JsonPath\\JsonPath::slice`
-    Adds an array slice selector ``[start:end:step]``::
+  Adds an array slice selector ``[start:end:step]``::
 
-        // Get books from index 1 up to (but not including) index 3
-        // Creates the path '$["store"]["book"][1:3]'
-        $path = (new JsonPath())->key('store')->key('book')->slice(1, 3);
+      // get books from index 1 up to (but not including) index 3
+      // creates the path '$["store"]["book"][1:3]'
+      $path = (new JsonPath())->key('store')->key('book')->slice(1, 3);
 
-        // Get every second book from the first four books
-        // Creates the path '$["store"]["book"][0:4:2]'
-        $path = (new JsonPath())->key('store')->key('book')->slice(0, 4, 2);
+      // get every second book from the first four books
+      // creates the path '$["store"]["book"][0:4:2]'
+      $path = (new JsonPath())->key('store')->key('book')->slice(0, 4, 2);
 
 * :method:`Symfony\\Component\\JsonPath\\JsonPath::filter`
-    Adds a filter expression. The expression string is the part that goes inside
-    the ``?()`` syntax::
+  Adds a filter expression. The expression string is the part that goes inside
+  the ``?()`` syntax::
 
-        // Get expensive books: '$["store"]["book"][?(@.price > 20)]'
-        $path = (new JsonPath())
-            ->key('store')
-            ->key('book')
-            ->filter('@.price > 20');
+      // get expensive books: '$["store"]["book"][?(@.price > 20)]'
+      $path = (new JsonPath())
+          ->key('store')
+          ->key('book')
+          ->filter('@.price > 20');
 
 Advanced Querying
 -----------------
 
 For a complete overview of advanced operators like wildcards and functions within
-filters, please refer to the `Querying with Expressions`_ section above. All these
-features are supported and can be combined with the programmatic builder where
+filters, refer to the `Querying with Expressions`_ section above. All these
+features are supported and can be combined with the programmatic builder when
 appropriate (e.g., inside a ``filter()`` expression).
 
 Error Handling
 --------------
 
-The component will throw specific exceptions for invalid input or queries:
+The component throws specific exceptions for invalid input or queries:
+
+* :class:`Symfony\\Component\\JsonPath\\Exception\\InvalidArgumentException`:
+  Thrown if the input to the ``JsonCrawler`` constructor is not a valid JSON string;
+* :class:`Symfony\\Component\\JsonPath\\Exception\\InvalidJsonStringInputException`:
+  Thrown during a ``find()`` call if the JSON string is malformed (e.g., syntax error);
+* :class:`Symfony\\Component\\JsonPath\\Exception\\JsonCrawlerException`:
+  Thrown for errors within the JsonPath expression itself, such as using an unknown function
 
-* :class:`Symfony\\Component\\JsonPath\\Exception\\InvalidArgumentException`: Thrown if the input to the ``JsonCrawler`` constructor is not a valid JSON string.
-* :class:`Symfony\\Component\\JsonPath\\Exception\\InvalidJsonStringInputException`: Thrown during a ``find()`` call if the JSON string is malformed (e.g., syntax error).
-* :class:`Symfony\\Component\\JsonPath\\Exception\\JsonCrawlerException`: Thrown for errors within the JsonPath expression itself, such as using an unknown function::
+Example of handling errors::
 
     use Symfony\Component\JsonPath\Exception\InvalidJsonStringInputException;
     use Symfony\Component\JsonPath\Exception\JsonCrawlerException;
 
     try {
-        // Example of malformed JSON
+        // the following line contains malformed JSON
         $crawler = new JsonCrawler('{"store": }');
         $crawler->find('$..*');
     } catch (InvalidJsonStringInputException $e) {
@@ -234,10 +239,10 @@ The component will throw specific exceptions for invalid input or queries:
     }
 
     try {
-        // Example of an invalid query
+        // the following line contains an invalid query
         $crawler->find('$.store.book[?unknown_function(@.price)]');
     } catch (JsonCrawlerException $e) {
         // ... handle error
     }
 
-.. _`RFC 9535 - JSONPath`: https://datatracker.ietf.org/doc/html/rfc9535
+.. _`RFC 9535 – JSONPath`: https://datatracker.ietf.org/doc/html/rfc9535

From 87ccbb5a8bf610a2f58bada88c682d21f594c91a Mon Sep 17 00:00:00 2001
From: Vincent Amstoutz <vincent.amstoutz@outlook.com>
Date: Tue, 17 Jun 2025 10:44:20 +0200
Subject: [PATCH 724/747] [JsonPath] Add test documentation for the component

---
 components/json_path.rst | 122 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 107 insertions(+), 15 deletions(-)

diff --git a/components/json_path.rst b/components/json_path.rst
index ec5db0e8e74..294eed98917 100644
--- a/components/json_path.rst
+++ b/components/json_path.rst
@@ -30,9 +30,9 @@ You can install the component in your project using Composer:
 Usage
 -----
 
-To start querying a JSON document, first create a :class:`Symfony\\Component\\JsonPath\\JsonCrawler`
-object from a JSON string. The following examples use this sample "bookstore"
-JSON data::
+To start querying a JSON document, first create a
+:class:`Symfony\\Component\\JsonPath\\JsonCrawler`object from a JSON string. The
+following examples use this sample "bookstore" JSON data::
 
     use Symfony\Component\JsonPath\JsonCrawler;
 
@@ -77,8 +77,9 @@ JSON data::
 
     $crawler = new JsonCrawler($json);
 
-Once you have the crawler instance, use its :method:`Symfony\\Component\\JsonPath\\JsonCrawler::find`
-method to start querying the data. This method returns an array of matching values.
+Once you have the crawler instance, use its
+:method:`Symfony\\Component\\JsonPath\\JsonCrawler::find` method to start
+querying the data. This method returns an array of matching values.
 
 Querying with Expressions
 -------------------------
@@ -97,9 +98,9 @@ of the document is represented by ``$``::
 
     // $titles is ['Sayings of the Century']
 
-Dot notation is the default, but JSONPath provides other syntaxes for cases where
-it doesn't work. Use bracket notation (``['...']``) when a key contains spaces
-or special characters::
+Dot notation is the default, but JSONPath provides other syntaxes for cases
+where it doesn't work. Use bracket notation (``['...']``) when a key contains
+spaces or special characters::
 
     // this is equivalent to the previous example
     $titles = $crawler->find('$["store"]["book"][0]["title"]');
@@ -119,7 +120,12 @@ you to find values without specifying the full path::
     // get all authors from anywhere in the document
     $authors = $crawler->find('$..author');
 
-    // $authors is ['Nigel Rees', 'Evelyn Waugh', 'Herman Melville', 'John Ronald Reuel Tolkien']
+    // $authors is equals to [
+        'Nigel Rees',
+        'Evelyn Waugh',
+        'Herman Melville',
+        'John Ronald Reuel Tolkien'
+    ]
 
 Filtering Results
 ~~~~~~~~~~~~~~~~~
@@ -135,8 +141,9 @@ Building Queries Programmatically
 
 For more dynamic or complex query building, use the fluent API provided
 by the :class:`Symfony\\Component\\JsonPath\\JsonPath` class. This lets you
-construct a query object step by step. The ``JsonPath`` object can then be passed
-to the crawler's :method:`Symfony\\Component\\JsonPath\\JsonCrawler::find` method.
+construct a query object step by step. The ``JsonPath`` object can then be
+passed to the crawler's
+:method:`Symfony\\Component\\JsonPath\\JsonCrawler::find` method.
 
 The main advantage of the programmatic builder is that it automatically handles
 escaping of keys and values, preventing syntax errors::
@@ -178,7 +185,8 @@ methods to build your query:
 * :method:`Symfony\\Component\\JsonPath\\JsonPath::index`
   Adds an array index selector. Index numbers start at ``0``.
 
-* :method:`Symfony\\Component\\JsonPath\\JsonPath::first` / :method:`Symfony\\Component\\JsonPath\\JsonPath::last`
+* :method:`Symfony\\Component\\JsonPath\\JsonPath::first` /
+  :method:`Symfony\\Component\\JsonPath\\JsonPath::last`
   Shortcuts for ``index(0)`` and ``index(-1)`` respectively::
 
       // get the last book: '$["store"]["book"][-1]'
@@ -213,17 +221,101 @@ filters, refer to the `Querying with Expressions`_ section above. All these
 features are supported and can be combined with the programmatic builder when
 appropriate (e.g., inside a ``filter()`` expression).
 
+Testing with JSON Assertions
+----------------------------
+
+The component provides a set of PHPUnit assertions to make testing JSON data
+more convenient. Use the
+:class:`Symfony\\Component\\JsonPath\\Test\\JsonPathAssertionsTrait`
+in your test class::
+
+    use PHPUnit\Framework\TestCase;
+    use Symfony\Component\JsonPath\Test\JsonPathAssertionsTrait;
+
+    class MyTest extends TestCase
+    {
+        use JsonPathAssertionsTrait;
+
+        public function testSomething(): void
+        {
+            $json = '{"books": [{"title": "A"}, {"title": "B"}]}';
+
+            self::assertJsonPathCount(2, '$.books[*]', $json);
+        }
+    }
+
+The trait provides the following assertion methods:
+
+* :method:`Symfony\\Component\\JsonPath\\Test\\JsonPathAssertionsTrait::assertJsonPathCount`
+  Asserts that the number of elements found by the JSONPath expression matches
+  an expected count::
+
+      $json = '{"a": [1, 2, 3]}';
+      self::assertJsonPathCount(3, '$.a[*]', $json);
+
+* :method:`Symfony\\Component\\JsonPath\\Test\\JsonPathAssertionsTrait::assertJsonPathEquals`
+  Asserts that the result of a JSONPath expression is equal to an expected
+  value. The comparison uses ``==`` (type coercion) instead of ``===``::
+
+      $json = '{"a": [1, 2, 3]}';
+
+      // passes because "1" == 1
+      self::assertJsonPathEquals(['1'], '$.a[0]', $json);
+
+* :method:`Symfony\\Component\\JsonPath\\Test\\JsonPathAssertionsTrait::assertJsonPathNotEquals`
+  Asserts that the result of a JSONPath expression is not equal to an expected
+  value. The comparison uses ``!=`` (type coercion) instead of ``!==``::
+
+      $json = '{"a": [1, 2, 3]}';
+      self::assertJsonPathNotEquals([42], '$.a[0]', $json);
+
+* :method:`Symfony\\Component\\JsonPath\\Test\\JsonPathAssertionsTrait::assertJsonPathSame`
+  Asserts that the result of a JSONPath expression is identical (``===``) to an
+  expected value. This is a strict comparison and does not perform type
+  coercion::
+
+      $json = '{"a": [1, 2, 3]}';
+
+      // fails because "1" !== 1
+      // self::assertJsonPathSame(['1'], '$.a[0]', $json);
+
+      self::assertJsonPathSame([1], '$.a[0]', $json);
+
+* :method:`Symfony\\Component\\JsonPath\\Test\\JsonPathAssertionsTrait::assertJsonPathNotSame`
+  Asserts that the result of a JSONPath expression is not identical (``!==``) to
+  an expected value::
+
+      $json = '{"a": [1, 2, 3]}';
+      self::assertJsonPathNotSame(['1'], '$.a[0]', $json);
+
+* :method:`Symfony\\Component\\JsonPath\\Test\\JsonPathAssertionsTrait::assertJsonPathContains`
+  Asserts that a given value is found within the array of results from the
+  JSONPath expression::
+
+      $json = '{"tags": ["php", "symfony", "json"]}';
+      self::assertJsonPathContains('symfony', '$.tags[*]', $json);
+
+* :method:`Symfony\\Component\\JsonPath\\Test\\JsonPathAssertionsTrait::assertJsonPathNotContains`
+  Asserts that a given value is NOT found within the array of results from the
+  JSONPath expression::
+
+      $json = '{"tags": ["php", "symfony", "json"]}';
+      self::assertJsonPathNotContains('java', '$.tags[*]', $json);
+
 Error Handling
 --------------
 
 The component throws specific exceptions for invalid input or queries:
 
 * :class:`Symfony\\Component\\JsonPath\\Exception\\InvalidArgumentException`:
-  Thrown if the input to the ``JsonCrawler`` constructor is not a valid JSON string;
+  Thrown if the input to the ``JsonCrawler`` constructor is not a valid JSON
+string;
 * :class:`Symfony\\Component\\JsonPath\\Exception\\InvalidJsonStringInputException`:
-  Thrown during a ``find()`` call if the JSON string is malformed (e.g., syntax error);
+  Thrown during a ``find()`` call if the JSON string is malformed
+(e.g., syntax error);
 * :class:`Symfony\\Component\\JsonPath\\Exception\\JsonCrawlerException`:
-  Thrown for errors within the JsonPath expression itself, such as using an unknown function
+  Thrown for errors within the JsonPath expression itself, such as using an
+  unknown function
 
 Example of handling errors::
 

From 230072e9f39b65092f60fd0e3c9344c329caa490 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Thu, 19 Jun 2025 16:24:18 +0200
Subject: [PATCH 725/747] Minor tweaks

---
 components/json_path.rst | 32 +++++++++++---------------------
 1 file changed, 11 insertions(+), 21 deletions(-)

diff --git a/components/json_path.rst b/components/json_path.rst
index 294eed98917..9db8e48885e 100644
--- a/components/json_path.rst
+++ b/components/json_path.rst
@@ -30,9 +30,9 @@ You can install the component in your project using Composer:
 Usage
 -----
 
-To start querying a JSON document, first create a
-:class:`Symfony\\Component\\JsonPath\\JsonCrawler`object from a JSON string. The
-following examples use this sample "bookstore" JSON data::
+To start querying a JSON document, first create a :class:`Symfony\\Component\\JsonPath\\JsonCrawler`
+object from a JSON string. The following examples use this sample "bookstore"
+JSON data::
 
     use Symfony\Component\JsonPath\JsonCrawler;
 
@@ -77,9 +77,8 @@ following examples use this sample "bookstore" JSON data::
 
     $crawler = new JsonCrawler($json);
 
-Once you have the crawler instance, use its
-:method:`Symfony\\Component\\JsonPath\\JsonCrawler::find` method to start
-querying the data. This method returns an array of matching values.
+Once you have the crawler instance, use its :method:`Symfony\\Component\\JsonPath\\JsonCrawler::find`
+method to start querying the data. This method returns an array of matching values.
 
 Querying with Expressions
 -------------------------
@@ -120,12 +119,7 @@ you to find values without specifying the full path::
     // get all authors from anywhere in the document
     $authors = $crawler->find('$..author');
 
-    // $authors is equals to [
-        'Nigel Rees',
-        'Evelyn Waugh',
-        'Herman Melville',
-        'John Ronald Reuel Tolkien'
-    ]
+    // $authors is ['Nigel Rees', 'Evelyn Waugh', 'Herman Melville', 'John Ronald Reuel Tolkien']
 
 Filtering Results
 ~~~~~~~~~~~~~~~~~
@@ -141,9 +135,8 @@ Building Queries Programmatically
 
 For more dynamic or complex query building, use the fluent API provided
 by the :class:`Symfony\\Component\\JsonPath\\JsonPath` class. This lets you
-construct a query object step by step. The ``JsonPath`` object can then be
-passed to the crawler's
-:method:`Symfony\\Component\\JsonPath\\JsonCrawler::find` method.
+construct a query object step by step. The ``JsonPath`` object can then be passed
+to the crawler's :method:`Symfony\\Component\\JsonPath\\JsonCrawler::find` method.
 
 The main advantage of the programmatic builder is that it automatically handles
 escaping of keys and values, preventing syntax errors::
@@ -225,8 +218,7 @@ Testing with JSON Assertions
 ----------------------------
 
 The component provides a set of PHPUnit assertions to make testing JSON data
-more convenient. Use the
-:class:`Symfony\\Component\\JsonPath\\Test\\JsonPathAssertionsTrait`
+more convenient. Use the :class:`Symfony\\Component\\JsonPath\\Test\\JsonPathAssertionsTrait`
 in your test class::
 
     use PHPUnit\Framework\TestCase;
@@ -308,11 +300,9 @@ Error Handling
 The component throws specific exceptions for invalid input or queries:
 
 * :class:`Symfony\\Component\\JsonPath\\Exception\\InvalidArgumentException`:
-  Thrown if the input to the ``JsonCrawler`` constructor is not a valid JSON
-string;
+  Thrown if the input to the ``JsonCrawler`` constructor is not a valid JSON string;
 * :class:`Symfony\\Component\\JsonPath\\Exception\\InvalidJsonStringInputException`:
-  Thrown during a ``find()`` call if the JSON string is malformed
-(e.g., syntax error);
+  Thrown during a ``find()`` call if the JSON string is malformed (e.g., syntax error);
 * :class:`Symfony\\Component\\JsonPath\\Exception\\JsonCrawlerException`:
   Thrown for errors within the JsonPath expression itself, such as using an
   unknown function

From 27f0a58c91b3f3fc74be9ac99bae618305fe34f7 Mon Sep 17 00:00:00 2001
From: Christian Flothmann <christian.flothmann@open.de>
Date: Sun, 22 Jun 2025 23:52:12 +0200
Subject: [PATCH 726/747] fix method role syntax

---
 messenger.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/messenger.rst b/messenger.rst
index 46ee188d68d..18fc5e03cec 100644
--- a/messenger.rst
+++ b/messenger.rst
@@ -2356,7 +2356,7 @@ will take care of creating a new process with the parameters you passed::
     }
 
 If you want to use shell features such as redirections or pipes, use the static
-factory :method:Symfony\\Component\\Process\\Messenger\\RunProcessMessage::fromShellCommandline::
+:method:`Symfony\\Component\\Process\\Messenger\\RunProcessMessage::fromShellCommandline` factory method::
 
     use Symfony\Component\Messenger\MessageBusInterface;
     use Symfony\Component\Process\Messenger\RunProcessMessage;

From 90be650dd8be29d435306bb80133d3db54e68bf8 Mon Sep 17 00:00:00 2001
From: Thomas Landauer <thomas@landauer.at>
Date: Mon, 23 Jun 2025 17:42:25 +0200
Subject: [PATCH 727/747] [Templates] Removing self-closing slashes

Page: https://symfony.com/doc/current/templates.html
---
 templates.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/templates.rst b/templates.rst
index 151ac5f71be..e895b4a6df3 100644
--- a/templates.rst
+++ b/templates.rst
@@ -304,10 +304,10 @@ You can now use the ``asset()`` function:
 .. code-block:: html+twig
 
     {# the image lives at "public/images/logo.png" #}
-    <img src="{{ asset('images/logo.png') }}" alt="Symfony!"/>
+    <img src="{{ asset('images/logo.png') }}" alt="Symfony!">
 
     {# the CSS file lives at "public/css/blog.css" #}
-    <link href="{{ asset('css/blog.css') }}" rel="stylesheet"/>
+    <link href="{{ asset('css/blog.css') }}" rel="stylesheet">
 
     {# the JS file lives at "public/bundles/acme/js/loader.js" #}
     <script src="{{ asset('bundles/acme/js/loader.js') }}"></script>
@@ -332,7 +332,7 @@ as follows:
 
 .. code-block:: html+twig
 
-    <img src="{{ absolute_url(asset('images/logo.png')) }}" alt="Symfony!"/>
+    <img src="{{ absolute_url(asset('images/logo.png')) }}" alt="Symfony!">
 
     <link rel="shortcut icon" href="{{ absolute_url('favicon.png') }}">
 
@@ -973,7 +973,7 @@ following code to display the user information is repeated in several places:
 
     {# ... #}
     <div class="user-profile">
-        <img src="{{ user.profileImageUrl }}" alt="{{ user.fullName }}"/>
+        <img src="{{ user.profileImageUrl }}" alt="{{ user.fullName }}">
         <p>{{ user.fullName }} - {{ user.email }}</p>
     </div>
 
@@ -1258,7 +1258,7 @@ In practice, the ``base.html.twig`` template would look like this:
             <meta charset="UTF-8">
             <title>{% block title %}My Application{% endblock %}</title>
             {% block stylesheets %}
-                <link rel="stylesheet" type="text/css" href="/css/base.css"/>
+                <link rel="stylesheet" type="text/css" href="/css/base.css">
             {% endblock %}
         </head>
         <body>

From e56a427ab53d52fbb0ee1b96554648a540855219 Mon Sep 17 00:00:00 2001
From: Pieter Oliver <pieter.oliver@nourishcare.com>
Date: Tue, 24 Jun 2025 12:22:57 +0100
Subject: [PATCH 728/747] Fix typo

---
 reference/constraints/Url.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/constraints/Url.rst b/reference/constraints/Url.rst
index 74f0d750dfd..1e9bb8ac62e 100644
--- a/reference/constraints/Url.rst
+++ b/reference/constraints/Url.rst
@@ -323,7 +323,7 @@ also relative URLs that contain no protocol (e.g. ``//example.com``).
     and will default to ``true`` in Symfony 8.0.
 
 By default, URLs like ``https://aaa`` or ``https://foobar`` are considered valid
-because they are tecnically correct according to the `URL spec`_. If you set this option
+because they are technically correct according to the `URL spec`_. If you set this option
 to ``true``, the host part of the URL will have to include a TLD (top-level domain
 name): e.g. ``https://example.com`` will be valid but ``https://example`` won't.
 

From 124be08d977cac7ef6296b6ed35496abf8443e05 Mon Sep 17 00:00:00 2001
From: Peter Potrowl <peter.potrowl@gmail.com>
Date: Thu, 19 Jun 2025 21:53:06 +0200
Subject: [PATCH 729/747] [Testing] Indicate how to use InMemoryUser in
 WebTestCase

---
 testing.rst | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/testing.rst b/testing.rst
index 9356f2013a7..862d66d59b8 100644
--- a/testing.rst
+++ b/testing.rst
@@ -714,6 +714,27 @@ stores in the session of the test client. If you need to define custom
 attributes in this token, you can use the ``tokenAttributes`` argument of the
 :method:`Symfony\\Bundle\\FrameworkBundle\\KernelBrowser::loginUser` method.
 
+You can also use :class:`Symfony\\Component\\Security\\Core\\User\\InMemoryUser` but you have to define those in the configuration first::
+
+.. code-block:: yaml
+
+    # config/packages/security.yaml
+    when@test:
+        security:
+            users_in_memory:
+                memory:
+                    users:
+                        admin: { password: password, roles: ROLE_ADMIN }
+
+and then log the user with::
+
+    // tests/Controller/ProfileControllerTest.php
+    use Symfony\Component\Security\Core\User\InMemoryUser;
+
+    $client = static::createClient();
+    $testUser = new InMemoryUser('admin', 'password', ['ROLE_ADMIN']);
+    $client->loginUser($testUser);
+
 To set a specific firewall (``main`` is set by default)::
 
     $client->loginUser($testUser, 'my_firewall');

From c42aead2daa69a6c5422955569f75eb09b8a24e9 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 27 Jun 2025 09:28:03 +0200
Subject: [PATCH 730/747] Minor reword

---
 testing.rst | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/testing.rst b/testing.rst
index 862d66d59b8..09cddfa55bb 100644
--- a/testing.rst
+++ b/testing.rst
@@ -714,7 +714,18 @@ stores in the session of the test client. If you need to define custom
 attributes in this token, you can use the ``tokenAttributes`` argument of the
 :method:`Symfony\\Bundle\\FrameworkBundle\\KernelBrowser::loginUser` method.
 
-You can also use :class:`Symfony\\Component\\Security\\Core\\User\\InMemoryUser` but you have to define those in the configuration first::
+You can also use an :ref:`in-memory user <security-memory-user-provider>` in your tests
+by instantiating :class:`Symfony\\Component\\Security\\Core\\User\\InMemoryUser` directly::
+
+    // tests/Controller/ProfileControllerTest.php
+    use Symfony\Component\Security\Core\User\InMemoryUser;
+
+    $client = static::createClient();
+    $testUser = new InMemoryUser('admin', 'password', ['ROLE_ADMIN']);
+    $client->loginUser($testUser);
+
+Before doing this, you must define the in-memory user in your test environment
+configuration to ensure it exists and can be authenticated::
 
 .. code-block:: yaml
 
@@ -726,15 +737,6 @@ You can also use :class:`Symfony\\Component\\Security\\Core\\User\\InMemoryUser`
                     users:
                         admin: { password: password, roles: ROLE_ADMIN }
 
-and then log the user with::
-
-    // tests/Controller/ProfileControllerTest.php
-    use Symfony\Component\Security\Core\User\InMemoryUser;
-
-    $client = static::createClient();
-    $testUser = new InMemoryUser('admin', 'password', ['ROLE_ADMIN']);
-    $client->loginUser($testUser);
-
 To set a specific firewall (``main`` is set by default)::
 
     $client->loginUser($testUser, 'my_firewall');

From 297146e5087feaf8b153b0bb7f15d2e559d6d801 Mon Sep 17 00:00:00 2001
From: Mathias Arlaud <mathias.arlaud@gmail.com>
Date: Thu, 19 Dec 2024 15:33:00 +0100
Subject: [PATCH 731/747] [Serializer] [JsonStreamer] Add streaming JSON
 documentation

---
 serializer.rst                |  32 ++
 serializer/streaming_json.rst | 675 ++++++++++++++++++++++++++++++++++
 2 files changed, 707 insertions(+)
 create mode 100644 serializer/streaming_json.rst

diff --git a/serializer.rst b/serializer.rst
index 4dd689a5ab5..93f370995ea 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -629,6 +629,38 @@ all the properties of the class::
         // ...
     }
 
+Serializing JSON using streams
+------------------------------
+
+Symfony is able of encoding PHP data structures to JSON streams and decoding
+JSON streams back into PHP data structures.
+
+To do so, it relies on the JsonStreamer component, which is designed for high
+efficiency and can process large JSON data incrementally without needing to
+load the entire content into memory.
+
+When deciding between the :doc:`Serializer component <serializer>` and the
+JsonStreamer component, consider the following:
+
+- **Serializer Component**: Ideal for scenarios requiring flexibility, such as
+  dynamically manipulating object shapes using normalizers and denormalizers,
+  or handling complex objects which multiple serialization representation.
+  Plus, it allows working with formats beyond JSON (and even with a custom
+  format of yours).
+
+- **JsonStreamer Component**: Ideal for simple objects and tasks that
+  demand high performance and minimal memory usage. It's particularly
+  effective when processing very large JSON datasets or in scenarios that
+  require streaming JSON in real-time without loading the entire dataset
+  into memory.
+
+Choosing between the two depends on your specific use case requirements.
+The JsonStreamer component is tailored to optimize for performance and memory
+efficiency, while the Serializer component offers flexibility and broader
+format support.
+
+Read more about streaming JSON in :doc:`/serializer/streaming_json`.
+
 Serializing to or from PHP Arrays
 ---------------------------------
 
diff --git a/serializer/streaming_json.rst b/serializer/streaming_json.rst
new file mode 100644
index 00000000000..3cf4de3ef0b
--- /dev/null
+++ b/serializer/streaming_json.rst
@@ -0,0 +1,675 @@
+Streaming JSON
+==============
+
+Symfony is able of encoding PHP data structures to JSON streams and decoding
+JSON streams back into PHP data structures.
+
+To do so, it relies on the JsonStreamer component, which is designed for high
+efficiency and can process large JSON data incrementally without needing to
+load the entire content into memory.
+
+.. tip::
+
+    This component is ideal for handling APIs or interacting with third-party
+    APIs. It transforms incoming JSON request payloads into PHP objects that
+    your application can work with. Similarly, it converts processed PHP
+    objects into a JSON stream for outgoing responses.
+
+Installation
+------------
+
+To install the JsonStreamer component in applications that use
+:ref:`Symfony Flex <symfony-flex>`, run this command:
+
+.. code-block:: terminal
+
+    $ composer require symfony/json-streamer
+
+.. include:: /components/require_autoload.rst.inc
+
+.. warning::
+
+    The JsonStreamer component is :doc:`experimental </contributing/code/experimental>`
+    and could be changed at any time without prior notice.
+
+Encoding objects
+----------------
+
+Let's say that we have the following ``Cat`` class::
+
+    // src/Dto/Cat.php
+    namespace App\Dto;
+
+    use Symfony\Component\JsonStreamer\Attribute\JsonStreamable;
+
+    #[JsonStreamable]
+    class Cat
+    {
+        public string $name;
+        public string $age;
+    }
+
+.. warning::
+
+    The JsonStreamer only works with PHP classes without constructor and
+    composed by public properties only.
+
+If you want to encode ``Cat`` objects to a JSON stream (e.g. to send them
+via an API response), you can get the ``json_streamer.stream_writer`` service by using
+the :class:`Symfony\\Component\\JsonStreamer\\StreamWriterInterface` parameter type
+with the ``$jsonStreamWriter`` name, and use the :method:`Symfony\\Component\\JsonStreamer\\StreamWriterInterface::write`
+method:
+
+.. configuration-block::
+
+    .. code-block:: php-symfony
+
+        // src/Controller/CatController.php
+        namespace App\Controller;
+
+        use App\Dto\Cat;
+        use App\Repository\CatRepository;
+        use Symfony\Component\HttpFoundation\StreamedResponse;
+        use Symfony\Component\JsonStreamer\StreamWriterInterface;
+        use Symfony\Component\TypeInfo\Type;
+
+        class CatController
+        {
+            public function retrieveCats(StreamWriterInterface $jsonStreamWriter, CatRepository $catRepository): StreamedResponse
+            {
+                $cats = $catRepository->findAll();
+                $type = Type::list(Type::object(Cat::class));
+
+                $json = $jsonStreamWriter->write($cats, $type);
+
+                return new StreamedResponse($json);
+            }
+        }
+
+    .. code-block:: php-standalone
+
+        use App\Dto\Cat;
+        use App\Repository\CatRepository;
+        use Symfony\Component\HttpFoundation\StreamedResponse;
+        use Symfony\Component\JsonStreamer\JsonStreamWriter;
+        use Symfony\Component\TypeInfo\Type;
+
+        // ...
+
+        $jsonWriter = JsonStreamWriter::create();
+
+        $cats = $catRepository->findAll();
+        $type = Type::list(Type::object(Cat::class));
+
+        $json = $jsonWriter->write($cats, $type);
+
+        $response = new StreamedResponse($json);
+
+        // ...
+
+.. note::
+
+    You can explicitly inject the ``json_streamer.stream_writer`` service by
+    using the ``#[Target('json_streamer.stream_writer')]`` autowire attribute.
+
+Decoding objects
+----------------
+
+Besides encoding objects to JSON, you can decode JSON to objects.
+
+To do so, you can get the ``json_streamer.stream_reader`` service by using the
+:class:`Symfony\\Component\\JsonStreamer\\StreamReaderInterface` parameter type
+with the ``$jsonStreamReader`` name, and use the :method:`Symfony\\Component\\JsonStreamer\\StreamReaderInterface::read`
+method:
+
+.. configuration-block::
+
+    .. code-block:: php-symfony
+
+        // src/Service/TombolaService.php
+        namespace App\Service;
+
+        use App\Dto\Cat;
+        use Symfony\Component\DependencyInjection\Attribute\Autowire;
+        use Symfony\Component\JsonStreamer\StreamReaderInterface;
+        use Symfony\Component\TypeInfo\Type;
+
+        class TombolaService
+        {
+            private string $catsJsonFile;
+
+            public function __construct(
+                private StreamReaderInterface $jsonStreamReader,
+                #[Autowire(param: 'kernel.root_dir')]
+                string $rootDir,
+            ) {
+                $this->catsJsonFile = sprintf('%s/var/cats.json', $rootDir);
+            }
+
+            public function pickTheTenthCat(): ?Cat
+            {
+                $jsonResource = fopen($this->catsJsonFile, 'r');
+                $type = Type::iterable(Type::object(Cat::class));
+
+                /** @var iterable<Cat> $cats */
+                $cats = $this->jsonStreamReader->read($jsonResource, $type);
+
+                $i = 0;
+                foreach ($cats as $cat) {
+                    if ($i === 9) {
+                        return $cat;
+                    }
+
+                    ++$i;
+                }
+
+                return null;
+            }
+
+            /**
+             * @return list<string>
+             */
+            public function listEligibleCatNames(): array
+            {
+                $json = file_get_contents($this->catsJsonFile);
+                $type = Type::iterable(Type::object(Cat::class));
+
+                /** @var iterable<Cat> $cats */
+                $cats = $this->jsonStreamReader->read($json, $type);
+
+                return array_map(fn(Cat $cat) => $cat->name, iterator_to_array($cats));
+            }
+        }
+
+    .. code-block:: php-standalone
+
+        // src/Service/TombolaService.php
+        namespace App\Service;
+
+        use App\Dto\Cat;
+        use Symfony\Component\JsonStreamer\JsonStreamReader;
+        use Symfony\Component\JsonStreamer\StreamReaderInterface;
+        use Symfony\Component\TypeInfo\Type;
+
+        class TombolaService
+        {
+            private StreamReaderInterface $jsonStreamReader;
+            private string $catsJsonFile;
+
+            public function __construct(
+                private string $catsJsonFile,
+            ) {
+                $this->jsonStreamReader = JsonStreamReader::create();
+            }
+
+            public function pickTheTenthCat(): ?Cat
+            {
+                $jsonResource = fopen($this->catsJsonFile, 'r');
+                $type = Type::iterable(Type::object(Cat::class));
+
+                /** @var iterable<Cat> $cats */
+                $cats = $this->jsonStreamReader->read($jsonResource, $type);
+
+                $i = 0;
+                foreach ($cats as $cat) {
+                    if ($i === 9) {
+                        return $cat;
+                    }
+
+                    ++$i;
+                }
+
+                return null;
+            }
+
+            /**
+             * @return list<string>
+             */
+            public function listEligibleCatNames(): array
+            {
+                $json = file_get_contents($this->catsJsonFile);
+                $type = Type::iterable(Type::object(Cat::class));
+
+                /** @var iterable<Cat> $cats */
+                $cats = $this->jsonStreamReader->read($json, $type);
+
+                return array_map(fn(Cat $cat) => $cat->name, iterator_to_array($cats));
+            }
+        }
+
+.. note::
+
+    You can explicitly inject the ``json_streamer.stream_reader`` service by
+    using the ``#[Target('json_streamer.stream_reader')]`` autowire attribute.
+
+The upper code demonstrates two different approaches to decoding JSON data
+using the JsonStreamer:
+
+* decoding from a stream (``pickTheTenthCat``)
+* decoding from a string (``listEligibleCatNames``).
+
+Both methods work with the same JSON data but differ in memory usage and
+speed optimization.
+
+
+Decoding from a stream
+~~~~~~~~~~~~~~~~~~~~~~
+
+In the ``pickTheTenthCat`` method, the JSON data is read as a stream using
+:phpfunction:`fopen`. Streams are useful when working with large files
+because the data is processed incrementally rather than loading the entire
+file into memory.
+
+To improve memory efficiency, the JsonStreamer creates `ghost objects`_
+instead of fully instantiating objects. Ghosts objects are lightweight
+placeholders that represent the objects but don't fully load their data
+into memory until it's needed. This approach reduces memory usage, especially
+for large datasets.
+
+* Advantage: Efficient memory usage, suitable for very large JSON files.
+* Disadvantage: Slightly slower than decoding a full string because data is
+  loaded on-demand.
+
+Decoding from a string
+~~~~~~~~~~~~~~~~~~~~~~
+
+In the ``listEligibleCatNames`` method, the entire JSON file is read into
+a string using :phpfunction:`file_get_contents`. This string is then passed
+to the decoder, which fully instantiates all the objects in the JSON data
+upfront.
+
+This approach is faster because all the objects are created immediately,
+making subsequent operations on the data quicker. However, it uses more
+memory since the entire file content and all objects are loaded at once.
+
+* Advantage: Faster processing, suitable for small to medium-sized JSON files.
+* Disadvantage: Higher memory usage, not ideal for large JSON files.
+
+.. tip::
+
+    Prefer stream decoding when working with large JSON files to conserve
+    memory.
+
+    Prefer string decoding instead when performance is more critical and the
+    JSON file size is manageable.
+
+Enabling PHPDoc reading
+-----------------------
+
+The JsonStreamer component can be able to process advanced PHPDoc type
+definitions, such as generics, and read/generate JSON for complex PHP
+objects.
+
+For example, let's consider this ``Shelter`` class that defines a generic
+``TAnimal`` type, which can be a ``Cat`` or a ``Dog``::
+
+    // src/Dto/Shelter.php
+    namespace App\Dto;
+
+    use Symfony\Component\JsonStreamer\Attribute\JsonStreamable;
+
+    /**
+     * @template TAnimal of Cat|Dog
+     */
+    #[JsonStreamable]
+    class Shelter
+    {
+        /**
+         * @var list<TAnimal>
+         */
+        public array $animals;
+    }
+
+
+To enable PHPDoc interpretation, run the following command:
+
+.. code-block:: terminal
+
+    $ composer require phpstan/phpdoc-parser
+
+Then, when encoding/decoding an instance of the ``Shelter`` class, you can
+specify the concrete type information, and the JsonStreamer will deal with the
+correct JSON structure::
+
+    use App\Dto\Cat;
+    use App\Dto\Shelter;
+    use Symfony\Component\TypeInfo\Type;
+
+    $json = <<<JSON
+    {
+      "animals": [
+        {"name": "Eva", "age": 29},
+        {...}
+      ]
+    }
+    JSON;
+
+    // maps the TAnimal template in Shelter to the Cat concrete type
+    $type = Type::generic(Type::object(Shelter::class), Type::object(Cat::class));
+
+    $catShelter = $jsonStreamReader->read($json, $type); // will be populated with Cat instances
+
+Configuring encoding/decoding
+-----------------------------
+
+While it's not recommended to change to object shape and values during
+encoding and decoding, it is sometimes unavoidable.
+
+Configuring the encoded name
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It is possible to configure the JSON key associated to a property thanks to
+the :class:`Symfony\\Component\\JsonStreamer\\Attribute\\StreamedName`
+attribute::
+
+    // src/Dto/Duck.php
+    namespace App\Dto;
+
+    use Symfony\Component\JsonStreamer\Attribute\JsonStreamable;
+    use Symfony\Component\JsonStreamer\Attribute\StreamedName;
+
+    #[JsonStreamable]
+    class Duck
+    {
+        #[StreamedName('@id')]
+        public string $id;
+    }
+
+By doing so, the ``Duck::$id`` property will be mapped to the ``@id`` JSON key::
+
+    use App\Dto\Duck;
+    use Symfony\Component\TypeInfo\Type;
+
+    // ...
+
+    $duck = new Duck();
+    $duck->id = '/ducks/daffy';
+
+    echo (string) $jsonStreamWriter->write($duck, Type::object(Duck::class));
+
+    // This will output:
+    // {
+    //   "@id": "/ducks/daffy"
+    // }
+
+Configuring the encoded value
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you need to manipulate the value related to a property during the encoding
+process, you can use the :class:`Symfony\\Component\\JsonStreamer\\Attribute\\ValueTransformer`
+attribute. Its ``nativeToStream`` property takes a callable, or a :ref:`value transformer service id <json-streamer-transform-with-services>`.
+
+When a callable is specified, it must either be a public static method or
+non-anonymous function with the following signature::
+
+    $transformer = function (mixed $data, array $options = []): mixed { /* ... */ };
+
+Then, you just have to specify the function identifier in the attribute::
+
+    // src/Dto/Duck.php
+    namespace App\Dto;
+
+    use Symfony\Component\JsonStreamer\Attribute\JsonStreamable;
+    use Symfony\Component\JsonStreamer\Attribute\ValueTransformer;
+
+    #[JsonStreamable]
+    class Duck
+    {
+        #[ValueTransformer(nativeToStream: 'strtoupper')]
+        public string $name;
+
+        #[ValueTransformer(nativeToStream: [self::class, 'formatHeight'])]
+        public int $height;
+
+        public static function formatHeight(int $value, array $options = []): string
+        {
+            return sprintf('%.2fcm', $value / 100);
+        }
+    }
+
+For example, by configuring the ``Duck`` class like above, the ``name`` and
+``height`` values will be transformed during encoding::
+
+    use App\Dto\Duck;
+    use Symfony\Component\TypeInfo\Type;
+
+    // ...
+
+    $duck = new Duck();
+    $duck->name = 'daffy';
+    $duck->height = 5083;
+
+    echo (string) $jsonStreamWriter->write($duck, Type::object(Duck::class));
+
+    // This will output:
+    // {
+    //   "name": "DAFFY",
+    //   "height": "50.83cm"
+    // }
+
+Configuring the decoded value
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can as well manipulate the value related to a property during decoding
+using the :class:`Symfony\\Component\\JsonStreamer\\Attribute\\ValueTransformer`
+attribute. Its ``streamToNative`` property can take either a callable or a :ref:`value transformer service id <json-streamer-transform-with-services>`.
+
+When a callable is specified, it must either be a public static method or
+a non-anonymous function with the following signature::
+
+    $valueTransformer = function (mixed $data, array $options = []): mixed { /* ... */ };
+
+You can specify a function identifier in the attribute as follows::
+
+    // src/Dto/Duck.php
+    namespace App\Dto;
+
+    use Symfony\Component\JsonStreamer\Attribute\JsonStreamable;
+    use Symfony\Component\JsonStreamer\Attribute\ValueTransformer;
+
+    #[JsonStreamable]
+    class Duck
+    {
+        #[ValueTransformer(streamToNative: [self::class, 'retrieveFirstName'])]
+        public string $firstName;
+
+        #[ValueTransformer(streamToNative: [self::class, 'retrieveLastName'])]
+        public string $lastName;
+
+        public static function retrieveFirstName(string $normalized, array $options = []): string
+        {
+            return explode(' ', $normalized)[0];
+        }
+
+        public static function retrieveLastName(string $normalized, array $options = []): string
+        {
+            return explode(' ', $normalized)[1];
+        }
+    }
+
+For instance, the above configuration for the ``Duck`` class will transform
+the `name` property from the input JSON during decoding::
+
+    use App\Dto\Duck;
+    use Symfony\Component\TypeInfo\Type;
+
+    // ...
+
+    $duck = $jsonStreamReader->read(
+        '{"name": "Daffy Duck"}',
+        Type::object(Duck::class),
+    );
+
+    // The $duck variable will contain:
+    // object(Duck)#1 (1) {
+    //   ["firstName"] => string(5) "Daffy"
+    //   ["lastName"] => string(4) "Duck"
+    // }
+
+.. _json-streamer-transform-with-services:
+
+Transform value using services
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When static methods or functions are not enough, you can transform the value
+thanks to a value transformer service.
+
+To do so, create a service implementing the :class:`Symfony\\Component\\JsonStreamer\\ValueTransformer\\ValueTransformerInterface`::
+
+    // src/Transformer/DogUrlTransformer.php
+    namespace App\Transformer;
+
+    use Symfony\Component\JsonStreamer\ValueTransformer\ValueTransformerInterface;
+    use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+    use Symfony\Component\TypeInfo\Type;
+
+    class DogUrlTransformer implements ValueTransformerInterface
+    {
+        public function __construct(
+            private UrlGeneratorInterface $urlGenerator,
+        ) {
+        }
+
+        public function transform(mixed $value, array $options = []): string
+        {
+            if (!is_int($value)) {
+                throw new \InvalidArgumentException(sprintf('The value must be "int", "%s" given.', get_debug_type($value)));
+            }
+
+            return $this->urlGenerator->generate('show_dog', ['id' => $value]);
+        }
+
+        public static function getStreamValueType(): Type
+        {
+            return Type::string();
+        }
+    }
+
+.. note::
+
+    The ``getStreamValueType`` method should return the type of what the value
+    will be in the JSON stream.
+
+And then, configure the :class:`Symfony\\Component\\JsonStreamer\\Attribute\\ValueTransformer`
+attribute to use that service::
+
+    // src/Dto/Dog.php
+    namespace App\Dto;
+
+    use App\Transformer\DogUrlTransformer;
+    use Symfony\Component\JsonStreamer\Attribute\JsonStreamable;
+    use Symfony\Component\JsonStreamer\Attribute\StreamedName;
+    use Symfony\Component\JsonStreamer\Attribute\ValueTransformer;
+
+    #[JsonStreamable]
+    class Dog
+    {
+        #[StreamedName('url')]
+        #[ValueTransformer(nativeToStream: DogUrlTransformer::class)]
+        public int $id;
+    }
+
+.. tip::
+
+    The value transformers will be intensively called during the
+    decoding and encoding. So be sure to keep them as fast as possible
+    (avoid calling external APIs or the database for example).
+
+Configure keys and values dynamically
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The JsonStreamer leverages services implementing the :class:`Symfony\\Component\\JsonStreamer\\Mapping\\PropertyMetadataLoaderInterface`
+to determine the shape and values of objects during encoding/decoding.
+
+These services are highly flexible and can be decorated to handle dynamic
+configurations, offering much greater power compared to using attributes::
+
+    namespace App\Streamer\SensitivePropertyMetadataLoader;
+
+    use App\Dto\SensitiveInterface;
+    use App\Streamer\ValueTransformer\EncryptorValueTransformer;
+    use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
+    use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated;
+    use Symfony\Component\JsonStreamer\Mapping\PropertyMetadata;
+    use Symfony\Component\JsonStreamer\Mapping\PropertyMetadataLoaderInterface;
+    use Symfony\Component\TypeInfo\Type;
+
+    #[AsDecorator('json_streamer.write.property_metadata_loader')]
+    class SensitivePropertyMetadataLoader implements PropertyMetadataLoaderInterface
+    {
+        public function __construct(
+            #[AutowireDecorated]
+            private PropertyMetadataLoaderInterface $decorated,
+        ) {
+        }
+
+        public function load(string $className, array $options = [], array $context = []): array
+        {
+            $propertyMetadataMap = $this->decorated->load($className, $options, $context);
+
+            if (!is_a($className, SensitiveInterface::class, true)) {
+                return $propertyMetadataMap;
+            }
+
+            // you can configure value transformers
+            foreach ($propertyMetadataMap as $jsonKey => $metadata) {
+                if (in_array($metadata->getName(), $className::getPropertiesToEncrypt(), true)) {
+                    $propertyMetadataMap[$jsonKey] = $metadata
+                        ->withType(Type::string())
+                        ->withAdditionalNativeToStreamValueTransformer(EncryptorValueTransformer::class);
+                }
+            }
+
+            // you can remove existing properties
+            foreach ($propertyMetadataMap as $jsonKey => $metadata) {
+                if (in_array($metadata->getName(), $className::getPropertiesToRemove(), true)) {
+                    unset($propertyMetadataMap[$jsonKey]);
+                }
+            }
+
+            // you can rename JSON keys
+            foreach ($propertyMetadataMap as $jsonKey => $metadata) {
+                $propertyMetadataMap[md5($jsonKey)] = $propertyMetadataMap[$jsonKey];
+                unset($propertyMetadataMap[$jsonKey]);
+            }
+
+            // you can add virtual properties
+            $propertyMetadataMap['is_sensitive'] = new PropertyMetadata(
+                name: 'theNameWontBeUsed',
+                type: Type::bool(),
+                nativeToStreamValueTransformers: [fn() => true],
+            );
+
+            return $propertyMetadataMap;
+        }
+    }
+
+However, this flexibility comes with complexity. Decorating property metadata
+loaders requires a deep understanding of the system.
+
+For most use cases, the attributes approach is sufficient, and the dynamic
+capabilities of property metadata loaders should be reserved for scenarios
+where their additional power is genuinely necessary.
+
+Marking objects as streamable
+-----------------------------
+
+The ``JsonStreamable`` attribute is used to mark a class as streamable.
+While this attribute is not mandatory, it is highly recommended because it
+plays a crucial role during the cache warm-up process by generating the
+files necessary for encoding and decoding operations, and thereby improving
+performance.
+
+It includes two properties: ``asObject`` and ``asList``. These properties
+define the structure in which the marked class should be prepared during the
+cache warm-up process::
+
+    use Symfony\Component\JsonStreamer\Attribute\JsonStreamable;
+
+    #[JsonStreamable(asObject: true, asList: true)]
+    class StreamableData
+    {
+        // ...
+    }
+
+.. _ghost objects: https://en.wikipedia.org/wiki/Lazy_loading#Ghost

From 0546a2ce4855254b05b7c95cc47c74e547381502 Mon Sep 17 00:00:00 2001
From: Yonel Ceruto <yonel.ceruto@scnd.com>
Date: Thu, 1 May 2025 11:52:20 -0400
Subject: [PATCH 732/747] [Console] Document invokable command

---
 .../console/changing_default_command.rst      |  14 +-
 components/console/events.rst                 |  28 ++-
 components/console/helpers/cursor.rst         |   8 +-
 .../console/helpers/debug_formatter.rst       |   9 +-
 .../console/helpers/formatterhelper.rst       |  12 +-
 components/console/helpers/processhelper.rst  |   2 +-
 components/console/helpers/questionhelper.rst |  62 ++++---
 components/console/helpers/table.rst          |  12 +-
 components/console/helpers/tree.rst           |  11 +-
 components/console/logger.rst                 |   5 +-
 components/console/single_command_tool.rst    |  11 +-
 components/process.rst                        |   9 +-
 console.rst                                   | 170 ++++++------------
 console/calling_commands.rst                  |  12 +-
 console/commands_as_services.rst              |  19 +-
 console/hide_commands.rst                     |   3 +-
 console/lockable_trait.rst                    |  15 +-
 console/style.rst                             |  53 +++---
 console/verbosity.rst                         |  13 +-
 logging/monolog_console.rst                   |  14 +-
 reference/attributes.rst                      |   2 +-
 routing.rst                                   |  18 +-
 scheduler.rst                                 |   6 +-
 23 files changed, 203 insertions(+), 305 deletions(-)

diff --git a/components/console/changing_default_command.rst b/components/console/changing_default_command.rst
index c69995ea395..2195bbd2697 100644
--- a/components/console/changing_default_command.rst
+++ b/components/console/changing_default_command.rst
@@ -9,20 +9,14 @@ name to the ``setDefaultCommand()`` method::
 
     use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Command\Command;
-    use Symfony\Component\Console\Input\InputInterface;
-    use Symfony\Component\Console\Output\OutputInterface;
+    use Symfony\Component\Console\Style\SymfonyStyle;
 
-    #[AsCommand(name: 'hello:world')]
+    #[AsCommand(name: 'hello:world', description: 'Outputs "Hello World"')]
     class HelloWorldCommand extends Command
     {
-        protected function configure(): void
+        public function __invoke(SymfonyStyle $io): int
         {
-            $this->setDescription('Outputs "Hello World"');
-        }
-
-        protected function execute(InputInterface $input, OutputInterface $output): int
-        {
-            $output->writeln('Hello World');
+            $io->writeln('Hello World');
 
             return Command::SUCCESS;
         }
diff --git a/components/console/events.rst b/components/console/events.rst
index e550025b7dd..699ba444747 100644
--- a/components/console/events.rst
+++ b/components/console/events.rst
@@ -209,36 +209,32 @@ method::
     for these constants to be available.
 
 If you use the Console component inside a Symfony application, commands can
-handle signals themselves. To do so, implement the
-:class:`Symfony\\Component\\Console\\Command\\SignalableCommandInterface` and subscribe to one or more signals::
+handle signals themselves by subscribing to the :class:`Symfony\\Component\\Console\\Event\\ConsoleSignalEvent` event::
 
-    // src/Command/SomeCommand.php
+    // src/Command/MyCommand.php
     namespace App\Command;
 
-    use Symfony\Component\Console\Command\Command;
-    use Symfony\Component\Console\Command\SignalableCommandInterface;
+    use Symfony\Component\Console\Attribute\AsCommand;
+    use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
 
-    class SomeCommand extends Command implements SignalableCommandInterface
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
     {
         // ...
 
-        public function getSubscribedSignals(): array
+        #[AsEventListener(ConsoleSignalEvent::class)]
+        public function handleSignal(ConsoleSignalEvent $event): void
         {
-            // return here any of the constants defined by PCNTL extension
-            return [\SIGINT, \SIGTERM];
-        }
-
-        public function handleSignal(int $signal): int|false
-        {
-            if (\SIGINT === $signal) {
+            // set here any of the constants defined by PCNTL extension
+            if (in_array($event->getHandlingSignal(), [\SIGINT, \SIGTERM], true)) {
                 // ...
             }
 
             // ...
 
-            // return an integer to set the exit code, or
+            // set an integer exit code, or
             // false to continue normal execution
-            return 0;
+            $event->setExitCode(0);
         }
     }
 
diff --git a/components/console/helpers/cursor.rst b/components/console/helpers/cursor.rst
index c5cab6c6d0b..63045f178ad 100644
--- a/components/console/helpers/cursor.rst
+++ b/components/console/helpers/cursor.rst
@@ -13,16 +13,16 @@ of the output:
     // src/Command/MyCommand.php
     namespace App\Command;
 
-    use Symfony\Component\Console\Command\Command;
+    use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Cursor;
-    use Symfony\Component\Console\Input\InputInterface;
     use Symfony\Component\Console\Output\OutputInterface;
 
-    class MyCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
     {
         // ...
 
-        public function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(OutputInterface $output): int
         {
             // ...
 
diff --git a/components/console/helpers/debug_formatter.rst b/components/console/helpers/debug_formatter.rst
index 10d3c67a79a..8fa59c319c9 100644
--- a/components/console/helpers/debug_formatter.rst
+++ b/components/console/helpers/debug_formatter.rst
@@ -10,15 +10,14 @@ this:
 .. image:: /_images/components/console/debug_formatter.png
     :alt: Console output, with the first line showing "RUN Running figlet", followed by lines showing the output of the command prefixed with "OUT" and "RES Finished the command" as last line in the output.
 
-Using the debug_formatter
+Using the Debug Formatter
 -------------------------
 
-The formatter is included in the default helper set and you can get it by
-calling :method:`Symfony\\Component\\Console\\Command\\Command::getHelper`::
+The debug formatter helper can be instantiated directly as shown::
 
-    $debugFormatter = $this->getHelper('debug_formatter');
+    $debugFormatter = new DebugFormatterHelper();
 
-The formatter accepts strings and returns a formatted string, which you then
+It accepts strings and returns a formatted string, which you then
 output to the console (or even log the information or do anything else).
 
 All methods of this helper have an identifier as the first argument. This is a
diff --git a/components/console/helpers/formatterhelper.rst b/components/console/helpers/formatterhelper.rst
index d2b19915a3a..4f83e66eecc 100644
--- a/components/console/helpers/formatterhelper.rst
+++ b/components/console/helpers/formatterhelper.rst
@@ -1,15 +1,11 @@
 Formatter Helper
 ================
 
-The Formatter helper provides functions to format the output with colors.
-You can do more advanced things with this helper than you can in
-:doc:`/console/coloring`.
+The :class:`Symfony\\Component\\Console\\Helper\\FormatterHelper` helper provides
+functions to format the output with colors. You can do more advanced things with
+this helper than you can in :doc:`/console/coloring`::
 
-The :class:`Symfony\\Component\\Console\\Helper\\FormatterHelper` is included
-in the default helper set and you can get it by calling
-:method:`Symfony\\Component\\Console\\Command\\Command::getHelper`::
-
-    $formatter = $this->getHelper('formatter');
+    $formatter = new FormatterHelper();
 
 The methods return a string, which you'll usually render to the console by
 passing it to the
diff --git a/components/console/helpers/processhelper.rst b/components/console/helpers/processhelper.rst
index b46d9f2e95f..df9a8efe45b 100644
--- a/components/console/helpers/processhelper.rst
+++ b/components/console/helpers/processhelper.rst
@@ -11,7 +11,7 @@ a very verbose verbosity (e.g. ``-vv``)::
 
     use Symfony\Component\Process\Process;
 
-    $helper = $this->getHelper('process');
+    $helper = new ProcessHelper();
     $process = new Process(['figlet', 'Symfony']);
 
     $helper->run($output, $process);
diff --git a/components/console/helpers/questionhelper.rst b/components/console/helpers/questionhelper.rst
index c7e064b16ca..6d22a2de2af 100644
--- a/components/console/helpers/questionhelper.rst
+++ b/components/console/helpers/questionhelper.rst
@@ -2,11 +2,9 @@ Question Helper
 ===============
 
 The :class:`Symfony\\Component\\Console\\Helper\\QuestionHelper` provides
-functions to ask the user for more information. It is included in the default
-helper set and you can get it by calling
-:method:`Symfony\\Component\\Console\\Command\\Command::getHelper`::
+functions to ask the user for more information::
 
-    $helper = $this->getHelper('question');
+    $helper = new QuestionHelper();
 
 The Question Helper has a single method
 :method:`Symfony\\Component\\Console\\Helper\\QuestionHelper::ask` that needs an
@@ -27,18 +25,18 @@ Suppose you want to confirm an action before actually executing it. Add
 the following to your command::
 
     // ...
+    use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Command\Command;
     use Symfony\Component\Console\Input\InputInterface;
     use Symfony\Component\Console\Output\OutputInterface;
     use Symfony\Component\Console\Question\ConfirmationQuestion;
 
-    class YourCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
     {
-        // ...
-
-        public function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(InputInterface $input, OutputInterface $output): int
         {
-            $helper = $this->getHelper('question');
+            $helper = new QuestionHelper();
             $question = new ConfirmationQuestion('Continue with this action?', false);
 
             if (!$helper->ask($input, $output, $question)) {
@@ -91,7 +89,7 @@ if you want to know a bundle name, you can add this to your command::
     use Symfony\Component\Console\Question\Question;
 
     // ...
-    public function execute(InputInterface $input, OutputInterface $output): int
+    public function __invoke(InputInterface $input, OutputInterface $output): int
     {
         // ...
         $question = new Question('Please enter the name of the bundle', 'AcmeDemoBundle');
@@ -121,10 +119,10 @@ but ``red`` could be set instead (could be more explicit)::
     use Symfony\Component\Console\Question\ChoiceQuestion;
 
     // ...
-    public function execute(InputInterface $input, OutputInterface $output): int
+    public function __invoke(InputInterface $input, OutputInterface $output): int
     {
         // ...
-        $helper = $this->getHelper('question');
+        $helper = new QuestionHelper();
         $question = new ChoiceQuestion(
             'Please select your favorite color (defaults to red)',
             // choices can also be PHP objects that implement __toString() method
@@ -184,10 +182,10 @@ this use :method:`Symfony\\Component\\Console\\Question\\ChoiceQuestion::setMult
     use Symfony\Component\Console\Question\ChoiceQuestion;
 
     // ...
-    public function execute(InputInterface $input, OutputInterface $output): int
+    public function __invoke(InputInterface $input, OutputInterface $output): int
     {
         // ...
-        $helper = $this->getHelper('question');
+        $helper = new QuestionHelper();
         $question = new ChoiceQuestion(
             'Please select your favorite colors (defaults to red and blue)',
             ['red', 'blue', 'yellow'],
@@ -218,10 +216,10 @@ will be autocompleted as the user types::
     use Symfony\Component\Console\Question\Question;
 
     // ...
-    public function execute(InputInterface $input, OutputInterface $output): int
+    public function __invoke(InputInterface $input, OutputInterface $output): int
     {
         // ...
-        $helper = $this->getHelper('question');
+        $helper = new QuestionHelper();
 
         $bundles = ['AcmeDemoBundle', 'AcmeBlogBundle', 'AcmeStoreBundle'];
         $question = new Question('Please enter the name of a bundle', 'FooBundle');
@@ -241,9 +239,9 @@ provide a callback function to dynamically generate suggestions::
     use Symfony\Component\Console\Question\Question;
 
     // ...
-    public function execute(InputInterface $input, OutputInterface $output): int
+    public function __invoke(InputInterface $input, OutputInterface $output): int
     {
-        $helper = $this->getHelper('question');
+        $helper = new QuestionHelper();
 
         // This function is called whenever the input changes and new
         // suggestions are needed.
@@ -282,10 +280,10 @@ You can also specify if you want to not trim the answer by setting it directly w
     use Symfony\Component\Console\Question\Question;
 
     // ...
-    public function execute(InputInterface $input, OutputInterface $output): int
+    public function __invoke(InputInterface $input, OutputInterface $output): int
     {
         // ...
-        $helper = $this->getHelper('question');
+        $helper = new QuestionHelper();
 
         $question = new Question('What is the name of the child?');
         $question->setTrimmable(false);
@@ -308,10 +306,10 @@ the response to a question should allow multiline answers by passing ``true`` to
     use Symfony\Component\Console\Question\Question;
 
     // ...
-    public function execute(InputInterface $input, OutputInterface $output): int
+    public function __invoke(InputInterface $input, OutputInterface $output): int
     {
         // ...
-        $helper = $this->getHelper('question');
+        $helper = new QuestionHelper();
 
         $question = new Question('How do you solve world peace?');
         $question->setMultiline(true);
@@ -335,10 +333,10 @@ convenient for passwords::
     use Symfony\Component\Console\Question\Question;
 
     // ...
-    public function execute(InputInterface $input, OutputInterface $output): int
+    public function __invoke(InputInterface $input, OutputInterface $output): int
     {
         // ...
-        $helper = $this->getHelper('question');
+        $helper = new QuestionHelper();
 
         $question = new Question('What is the database password?');
         $question->setHidden(true);
@@ -372,10 +370,10 @@ convenient for passwords::
         use Symfony\Component\Console\Question\ChoiceQuestion;
 
         // ...
-        public function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(InputInterface $input, OutputInterface $output): int
         {
             // ...
-            $helper = $this->getHelper('question');
+            $helper = new QuestionHelper();
             QuestionHelper::disableStty();
 
             // ...
@@ -396,10 +394,10 @@ method::
     use Symfony\Component\Console\Question\Question;
 
     // ...
-    public function execute(InputInterface $input, OutputInterface $output): int
+    public function __invoke(InputInterface $input, OutputInterface $output): int
     {
         // ...
-        $helper = $this->getHelper('question');
+        $helper = new QuestionHelper();
 
         $question = new Question('Please enter the name of the bundle', 'AcmeDemoBundle');
         $question->setNormalizer(function (string $value): string {
@@ -434,10 +432,10 @@ method::
     use Symfony\Component\Console\Question\Question;
 
     // ...
-    public function execute(InputInterface $input, OutputInterface $output): int
+    public function __invoke(InputInterface $input, OutputInterface $output): int
     {
         // ...
-        $helper = $this->getHelper('question');
+        $helper = new QuestionHelper();
 
         $question = new Question('Please enter the name of the bundle', 'AcmeDemoBundle');
         $question->setValidator(function (string $answer): string {
@@ -494,10 +492,10 @@ You can also use a validator with a hidden question::
     use Symfony\Component\Console\Question\Question;
 
     // ...
-    public function execute(InputInterface $input, OutputInterface $output): int
+    public function __invoke(InputInterface $input, OutputInterface $output): int
     {
         // ...
-        $helper = $this->getHelper('question');
+        $helper = new QuestionHelper();
 
         $question = new Question('Please enter your password');
         $question->setNormalizer(function (?string $value): string {
diff --git a/components/console/helpers/table.rst b/components/console/helpers/table.rst
index fe267599caf..e36b1570b70 100644
--- a/components/console/helpers/table.rst
+++ b/components/console/helpers/table.rst
@@ -10,15 +10,16 @@ features, use the ``Table`` console helper explained in this article.
 To display a table, use :class:`Symfony\\Component\\Console\\Helper\\Table`,
 set the headers, set the rows and then render the table::
 
+    use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Command\Command;
     use Symfony\Component\Console\Helper\Table;
-    use Symfony\Component\Console\Input\InputInterface;
     use Symfony\Component\Console\Output\OutputInterface;
     // ...
 
-    class SomeCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
     {
-        public function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(OutputInterface $output): int
         {
             $table = new Table($output);
             $table
@@ -472,9 +473,10 @@ The only requirement to append rows is that the table must be rendered inside a
     use Symfony\Component\Console\Helper\Table;
     // ...
 
-    class SomeCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
     {
-        public function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(OutputInterface $output): int
         {
             $section = $output->section();
             $table = new Table($section);
diff --git a/components/console/helpers/tree.rst b/components/console/helpers/tree.rst
index b5839b74a26..3c41377ac37 100644
--- a/components/console/helpers/tree.rst
+++ b/components/console/helpers/tree.rst
@@ -26,22 +26,17 @@ inside your console command::
     namespace App\Command;
 
     use Symfony\Component\Console\Attribute\AsCommand;
-    use Symfony\Component\Console\Command\Command;
     use Symfony\Component\Console\Helper\TreeHelper;
     use Symfony\Component\Console\Helper\TreeNode;
-    use Symfony\Component\Console\Input\InputInterface;
-    use Symfony\Component\Console\Output\OutputInterface;
     use Symfony\Component\Console\Style\SymfonyStyle;
 
-    #[AsCommand(name: 'app:some-command', description: '...')]
-    class SomeCommand extends Command
+    #[AsCommand(name: 'app:my-command', description: '...')]
+    class MyCommand
     {
         // ...
 
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(SymfonyStyle $io): int
         {
-            $io = new SymfonyStyle($input, $output);
-
             $node = TreeNode::fromValues([
                 'config/',
                 'public/',
diff --git a/components/console/logger.rst b/components/console/logger.rst
index c3d5c447a89..cc182821a0a 100644
--- a/components/console/logger.rst
+++ b/components/console/logger.rst
@@ -34,7 +34,6 @@ You can rely on the logger to use this dependency inside a command::
     use Acme\MyDependency;
     use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Command\Command;
-    use Symfony\Component\Console\Input\InputInterface;
     use Symfony\Component\Console\Logger\ConsoleLogger;
     use Symfony\Component\Console\Output\OutputInterface;
 
@@ -42,9 +41,9 @@ You can rely on the logger to use this dependency inside a command::
         name: 'my:command',
         description: 'Use an external dependency requiring a PSR-3 logger'
     )]
-    class MyCommand extends Command
+    class MyCommand
     {
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(OutputInterface $output): int
         {
             $logger = new ConsoleLogger($output);
 
diff --git a/components/console/single_command_tool.rst b/components/console/single_command_tool.rst
index 97cb09bf030..9c6b06537e2 100644
--- a/components/console/single_command_tool.rst
+++ b/components/console/single_command_tool.rst
@@ -9,19 +9,18 @@ it is possible to remove this need by declaring a single command application::
     <?php
     require __DIR__.'/vendor/autoload.php';
 
-    use Symfony\Component\Console\Input\InputArgument;
-    use Symfony\Component\Console\Input\InputInterface;
-    use Symfony\Component\Console\Input\InputOption;
+    use Symfony\Component\Console\Attribute\Argument;
+    use Symfony\Component\Console\Attribute\Option;
     use Symfony\Component\Console\Output\OutputInterface;
     use Symfony\Component\Console\SingleCommandApplication;
 
     (new SingleCommandApplication())
         ->setName('My Super Command') // Optional
         ->setVersion('1.0.0') // Optional
-        ->addArgument('foo', InputArgument::OPTIONAL, 'The directory')
-        ->addOption('bar', null, InputOption::VALUE_REQUIRED)
-        ->setCode(function (InputInterface $input, OutputInterface $output): int {
+        ->setCode(function (OutputInterface $output, #[Argument] string $foo = 'The directory', #[Option] string $bar = ''): int {
             // output arguments and options
+
+            return 0;
         })
         ->run();
 
diff --git a/components/process.rst b/components/process.rst
index 7552537e82e..9c25c931510 100644
--- a/components/process.rst
+++ b/components/process.rst
@@ -430,11 +430,14 @@ However, if you run the command via the Symfony ``Process`` class, PHP will use
 the settings defined in the ``php.ini`` file. You can solve this issue by using
 the :class:`Symfony\\Component\\Process\\PhpSubprocess` class to run the command::
 
+    use Symfony\Component\Console\Attribute\AsCommand;
+    use Symfony\Component\Console\Style\SymfonyStyle;
     use Symfony\Component\Process\Process;
 
-    class MyCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
     {
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(SymfonyStyle $io): int
         {
             // the memory_limit (and any other config option) of this command is
             // the one defined in php.ini instead of the new values (optionally)
@@ -444,6 +447,8 @@ the :class:`Symfony\\Component\\Process\\PhpSubprocess` class to run the command
             // the memory_limit (and any other config option) of this command takes
             // into account the values (optionally) passed via the '-d' command option
             $childProcess = new PhpSubprocess(['bin/console', 'cache:pool:prune']);
+
+            return 0;
         }
     }
 
diff --git a/console.rst b/console.rst
index 24fab9885da..4a4161a2014 100644
--- a/console.rst
+++ b/console.rst
@@ -107,26 +107,25 @@ completion (by default, by pressing the Tab key).
     installation instructions for your shell. The Symfony CLI will provide
     completion for the ``console`` and ``composer`` commands.
 
+.. _console_creating-command:
+
 Creating a Command
 ------------------
 
-Commands are defined in classes extending
-:class:`Symfony\\Component\\Console\\Command\\Command`. For example, you may
-want a command to create a user::
+Commands are defined in classes, for example, you may want a command to create a user. Use
+the ``#[AsCommand]`` attribute to auto-register it::
 
     // src/Command/CreateUserCommand.php
     namespace App\Command;
 
     use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Command\Command;
-    use Symfony\Component\Console\Input\InputInterface;
-    use Symfony\Component\Console\Output\OutputInterface;
 
     // the name of the command is what users type after "php bin/console"
     #[AsCommand(name: 'app:create-user')]
-    class CreateUserCommand extends Command
+    class CreateUserCommand
     {
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(): int
         {
             // ... put here the code to create the user
 
@@ -147,104 +146,54 @@ want a command to create a user::
         }
     }
 
-Configuring the Command
-~~~~~~~~~~~~~~~~~~~~~~~
-
-You can optionally define a description, help message and the
-:doc:`input options and arguments </console/input>` by overriding the
-``configure()`` method::
+If you can't use PHP attributes, register the command as a service and
+:doc:`tag it </service_container/tags>` with the ``console.command`` tag. If you're using the
+:ref:`default services.yaml configuration <service-container-services-load-example>`,
+this is already done for you, thanks to :ref:`autoconfiguration <services-autoconfigure>`.
 
-    // src/Command/CreateUserCommand.php
+You can also use ``#[AsCommand]`` to add a description and longer help text for the command::
 
-    // ...
-    class CreateUserCommand extends Command
+    #[AsCommand(
+        name: 'app:create-user',
+        description: 'Creates a new user.', // the command description shown when running "php bin/console list"
+        help: 'This command allows you to create a user...', // the command help shown when running the command with the "--help" option
+    )]
+    class CreateUserCommand
     {
-        // ...
-        protected function configure(): void
+        public function __invoke(): int
         {
-            $this
-                // the command description shown when running "php bin/console list"
-                ->setDescription('Creates a new user.')
-                // the command help shown when running the command with the "--help" option
-                ->setHelp('This command allows you to create a user...')
-            ;
+            // ...
         }
     }
 
-.. tip::
-
-    Using the ``#[AsCommand]`` attribute to define a description instead of
-    using the ``setDescription()`` method allows to get the command description without
-    instantiating its class. This makes the ``php bin/console list`` command run
-    much faster.
-
-    If you want to always run the ``list`` command fast, add the ``--short`` option
-    to it (``php bin/console list --short``). This will avoid instantiating command
-    classes, but it won't show any description for commands that use the
-    ``setDescription()`` method instead of the attribute to define the command
-    description.
-
-The ``configure()`` method is called automatically at the end of the command
-constructor. If your command defines its own constructor, set the properties
-first and then call to the parent constructor, to make those properties
-available in the ``configure()`` method::
+Additionally, you can extend the :class:`Symfony\\Component\\Console\\Command\\Command` class to
+leverage advanced features like lifecycle hooks (e.g. :method:`Symfony\\Component\\Console\\Command\\Command::initialize` and
+and :method:`Symfony\\Component\\Console\\Command\\Command::interact`)::
 
-    // ...
+    use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Command\Command;
-    use Symfony\Component\Console\Input\InputArgument;
+    use Symfony\Component\Console\Input\InputInterface;
+    use Symfony\Component\Console\Output\OutputInterface;
 
+    #[AsCommand(name: 'app:create-user')]
     class CreateUserCommand extends Command
     {
-        // ...
-
-        public function __construct(bool $requirePassword = false)
+        public function initialize(InputInterface $input, OutputInterface $output): void
         {
-            // best practices recommend to call the parent constructor first and
-            // then set your own properties. That wouldn't work in this case
-            // because configure() needs the properties set in this constructor
-            $this->requirePassword = $requirePassword;
-
-            parent::__construct();
+            // ...
         }
 
-        protected function configure(): void
+        public function interact(InputInterface $input, OutputInterface $output): void
         {
-            $this
-                // ...
-                ->addArgument('password', $this->requirePassword ? InputArgument::REQUIRED : InputArgument::OPTIONAL, 'User password')
-            ;
+            // ...
         }
-    }
-
-.. _console_registering-the-command:
-
-Registering the Command
-~~~~~~~~~~~~~~~~~~~~~~~
 
-You can register the command by adding the ``AsCommand`` attribute to it::
-
-    // src/Command/CreateUserCommand.php
-    namespace App\Command;
-
-    use Symfony\Component\Console\Attribute\AsCommand;
-    use Symfony\Component\Console\Command\Command;
-
-    #[AsCommand(
-        name: 'app:create-user',
-        description: 'Creates a new user.',
-        hidden: false,
-        aliases: ['app:add-user']
-    )]
-    class CreateUserCommand extends Command
-    {
-        // ...
+        public function __invoke(): int
+        {
+            // ...
+        }
     }
 
-If you can't use PHP attributes, register the command as a service and
-:doc:`tag it </service_container/tags>` with the ``console.command`` tag. If you're using the
-:ref:`default services.yaml configuration <service-container-services-load-example>`,
-this is already done for you, thanks to :ref:`autoconfiguration <services-autoconfigure>`.
-
 Running the Command
 ~~~~~~~~~~~~~~~~~~~
 
@@ -255,16 +204,16 @@ After configuring and registering the command, you can run it in the terminal:
     $ php bin/console app:create-user
 
 As you might expect, this command will do nothing as you didn't write any logic
-yet. Add your own logic inside the ``execute()`` method.
+yet. Add your own logic inside the ``__invoke()`` method.
 
 Console Output
 --------------
 
-The ``execute()`` method has access to the output stream to write messages to
+The ``__invoke()`` method has access to the output stream to write messages to
 the console::
 
     // ...
-    protected function execute(InputInterface $input, OutputInterface $output): int
+    public function __invoke(OutputInterface $output): int
     {
         // outputs multiple lines to the console (adding "\n" at the end of each line)
         $output->writeln([
@@ -315,9 +264,10 @@ method, which returns an instance of
     // ...
     use Symfony\Component\Console\Output\ConsoleOutputInterface;
 
-    class MyCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
     {
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(OutputInterface $output): int
         {
             if (!$output instanceof ConsoleOutputInterface) {
                 throw new \LogicException('This command accepts only an instance of "ConsoleOutputInterface".');
@@ -376,20 +326,12 @@ Console Input
 
 Use input options or arguments to pass information to the command::
 
-    use Symfony\Component\Console\Input\InputArgument;
+    use Symfony\Component\Console\Attribute\Argument;
 
-    // ...
-    protected function configure(): void
-    {
-        $this
-            // configure an argument
-            ->addArgument('username', InputArgument::REQUIRED, 'The username of the user.')
-            // ...
-        ;
-    }
-
-    // ...
-    public function execute(InputInterface $input, OutputInterface $output): int
+    // The #[Argument] attribute configures $username as a
+    // required input argument and its value is automatically
+    // passed to this parameter
+    public function __invoke(#[Argument('The username of the user.')] string $username, OutputInterface $output): int
     {
         $output->writeln([
             'User Creator',
@@ -397,8 +339,7 @@ Use input options or arguments to pass information to the command::
             '',
         ]);
 
-        // retrieve the argument value using getArgument()
-        $output->writeln('Username: '.$input->getArgument('username'));
+        $output->writeln('Username: '.$username);
 
         return Command::SUCCESS;
     }
@@ -428,23 +369,22 @@ as a service, you can use normal dependency injection. Imagine you have a
 
     // ...
     use App\Service\UserManager;
-    use Symfony\Component\Console\Command\Command;
+    use Symfony\Component\Console\Attribute\Argument;
+    use Symfony\Component\Console\Attribute\AsCommand;
 
-    class CreateUserCommand extends Command
+    #[AsCommand(name: 'app:create-user')]
+    class CreateUserCommand
     {
         public function __construct(
-            private UserManager $userManager,
-        ){
-            parent::__construct();
+            private UserManager $userManager
+        ) {
         }
 
-        // ...
-
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(#[Argument] string $username, OutputInterface $output): int
         {
             // ...
 
-            $this->userManager->create($input->getArgument('username'));
+            $this->userManager->create($username);
 
             $output->writeln('User successfully generated!');
 
@@ -472,7 +412,7 @@ command:
     Note that it will not be called when the command is run without interaction
     (e.g. when passing the ``--no-interaction`` global option flag).
 
-:method:`Symfony\\Component\\Console\\Command\\Command::execute` *(required)*
+``__invoke()`` *(required)*
     This method is executed after ``interact()`` and ``initialize()``.
     It contains the logic you want the command to execute and it must
     return an integer which will be used as the command `exit status`_.
diff --git a/console/calling_commands.rst b/console/calling_commands.rst
index dd1f0b12ff9..875ead15d2d 100644
--- a/console/calling_commands.rst
+++ b/console/calling_commands.rst
@@ -14,20 +14,18 @@ arguments and options you want to pass to the command. The command name must be
 the first argument.
 
 Eventually, calling the ``doRun()`` method actually runs the command and returns
-the returned code from the command (return value from command ``execute()``
+the returned code from the command (return value from command ``__invoke()``
 method)::
 
     // ...
-    use Symfony\Component\Console\Command;
+    use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Input\ArrayInput;
-    use Symfony\Component\Console\Input\InputInterface;
     use Symfony\Component\Console\Output\OutputInterface;
 
-    class CreateUserCommand extends Command
+    #[AsCommand(name: 'app:create-user')]
+    class CreateUserCommand
     {
-        // ...
-
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(OutputInterface $output): int
         {
             $greetInput = new ArrayInput([
                 // the command name is passed as first argument
diff --git a/console/commands_as_services.rst b/console/commands_as_services.rst
index 1393879a1df..ed5b99f9cb4 100644
--- a/console/commands_as_services.rst
+++ b/console/commands_as_services.rst
@@ -16,27 +16,16 @@ For example, suppose you want to log something from within your command::
 
     use Psr\Log\LoggerInterface;
     use Symfony\Component\Console\Attribute\AsCommand;
-    use Symfony\Component\Console\Command\Command;
-    use Symfony\Component\Console\Input\InputInterface;
-    use Symfony\Component\Console\Output\OutputInterface;
 
-    #[AsCommand(name: 'app:sunshine')]
-    class SunshineCommand extends Command
+    #[AsCommand(name: 'app:sunshine', description: 'Good morning!')]
+    class SunshineCommand
     {
         public function __construct(
             private LoggerInterface $logger,
         ) {
-            // you *must* call the parent constructor
-            parent::__construct();
-        }
-
-        protected function configure(): void
-        {
-            $this
-                ->setDescription('Good morning!');
         }
 
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(): int
         {
             $this->logger->info('Waking up the sun');
             // ...
@@ -70,7 +59,7 @@ To make your command lazily loaded, either define its name using the PHP
     // ...
 
     #[AsCommand(name: 'app:sunshine')]
-    class SunshineCommand extends Command
+    class SunshineCommand
     {
         // ...
     }
diff --git a/console/hide_commands.rst b/console/hide_commands.rst
index 44a69d09289..4ab9d3a6dad 100644
--- a/console/hide_commands.rst
+++ b/console/hide_commands.rst
@@ -15,10 +15,9 @@ the ``hidden`` property of the ``AsCommand`` attribute::
     namespace App\Command;
 
     use Symfony\Component\Console\Attribute\AsCommand;
-    use Symfony\Component\Console\Command\Command;
 
     #[AsCommand(name: 'app:legacy', hidden: true)]
-    class LegacyCommand extends Command
+    class LegacyCommand
     {
         // ...
     }
diff --git a/console/lockable_trait.rst b/console/lockable_trait.rst
index 0f4a4900e17..2a4fd64ffaf 100644
--- a/console/lockable_trait.rst
+++ b/console/lockable_trait.rst
@@ -13,19 +13,17 @@ that adds two convenient methods to lock and release commands::
     // ...
     use Symfony\Component\Console\Command\Command;
     use Symfony\Component\Console\Command\LockableTrait;
-    use Symfony\Component\Console\Input\InputInterface;
-    use Symfony\Component\Console\Output\OutputInterface;
+    use Symfony\Component\Console\Style\SymfonyStyle;
 
-    class UpdateContentsCommand extends Command
+    #[AsCommand(name: 'contents:update')]
+    class UpdateContentsCommand
     {
         use LockableTrait;
 
-        // ...
-
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(SymfonyStyle $io): int
         {
             if (!$this->lock()) {
-                $output->writeln('The command is already running in another process.');
+                $io->writeln('The command is already running in another process.');
 
                 return Command::SUCCESS;
             }
@@ -52,7 +50,8 @@ a ``$lockFactory`` property with your own lock factory::
     use Symfony\Component\Console\Command\LockableTrait;
     use Symfony\Component\Lock\LockFactory;
 
-    class UpdateContentsCommand extends Command
+    #[AsCommand(name: 'contents:update')]
+    class UpdateContentsCommand
     {
         use LockableTrait;
 
diff --git a/console/style.rst b/console/style.rst
index e1e5df38ffe..a9f71a9d7a8 100644
--- a/console/style.rst
+++ b/console/style.rst
@@ -7,18 +7,18 @@ questions to the user involves a lot of repetitive code.
 
 Consider for example the code used to display the title of the following command::
 
-    // src/Command/GreetCommand.php
+    // src/Command/MyCommand.php
     namespace App\Command;
 
+    use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Command\Command;
     use Symfony\Component\Console\Input\InputInterface;
     use Symfony\Component\Console\Output\OutputInterface;
 
-    class GreetCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
     {
-        // ...
-
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(InputInterface $input, OutputInterface $output): int
         {
             $output->writeln([
                 '<info>Lorem Ipsum Dolor Sit Amet</>',
@@ -42,26 +42,22 @@ which allow to create *semantic* commands and forget about their styling.
 Basic Usage
 -----------
 
-In your command, instantiate the :class:`Symfony\\Component\\Console\\Style\\SymfonyStyle`
-class and pass the ``$input`` and ``$output`` variables as its arguments. Then,
-you can start using any of its helpers, such as ``title()``, which displays the
-title of the command::
+In your ``__invoke()`` method, add an argument of type :class:`Symfony\\Component\\Console\\Style\\SymfonyStyle`.
+Then, you can start using any of its helpers, such as ``title()``, which
+displays the title of the command::
 
-    // src/Command/GreetCommand.php
+    // src/Command/MyCommand.php
     namespace App\Command;
 
+    use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Command\Command;
-    use Symfony\Component\Console\Input\InputInterface;
-    use Symfony\Component\Console\Output\OutputInterface;
     use Symfony\Component\Console\Style\SymfonyStyle;
 
-    class GreetCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
     {
-        // ...
-
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(SymfonyStyle $io): int
         {
-            $io = new SymfonyStyle($input, $output);
             $io->title('Lorem Ipsum Dolor Sit Amet');
 
             // ...
@@ -448,19 +444,17 @@ long they are. This is done to enable clickable URLs in terminals that support t
 
 If you prefer to wrap all contents, including URLs, use this method::
 
-    // src/Command/GreetCommand.php
+    // src/Command/MyCommand.php
     namespace App\Command;
 
     // ...
     use Symfony\Component\Console\Style\SymfonyStyle;
 
-    class GreetCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
     {
-        // ...
-
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(SymfonyStyle $io): int
         {
-            $io = new SymfonyStyle($input, $output);
             $io->getOutputWrapper()->setAllowCutUrls(true);
 
             // ...
@@ -487,7 +481,7 @@ Then, instantiate this custom class instead of the default ``SymfonyStyle`` in
 your commands. Thanks to the ``StyleInterface`` you won't need to change the code
 of your commands to change their appearance::
 
-    // src/Command/GreetCommand.php
+    // src/Command/MyCommand.php
     namespace App\Console;
 
     use App\Console\CustomStyle;
@@ -495,16 +489,11 @@ of your commands to change their appearance::
     use Symfony\Component\Console\Input\InputInterface;
     use Symfony\Component\Console\Output\OutputInterface;
 
-    class GreetCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
     {
-        // ...
-
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(InputInterface $input, OutputInterface $output): int
         {
-            // Before
-            $io = new SymfonyStyle($input, $output);
-
-            // After
             $io = new CustomStyle($input, $output);
 
             // ...
diff --git a/console/verbosity.rst b/console/verbosity.rst
index 9910dca0c3d..cbbb1663895 100644
--- a/console/verbosity.rst
+++ b/console/verbosity.rst
@@ -49,21 +49,22 @@ It is possible to print a message in a command for only a specific verbosity
 level. For example::
 
     // ...
+    use Symfony\Component\Console\Attribute\Argument;
+    use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Command\Command;
     use Symfony\Component\Console\Input\InputInterface;
     use Symfony\Component\Console\Output\OutputInterface;
 
-    class CreateUserCommand extends Command
+    #[AsCommand(name: 'app:create-user')]
+    class CreateUserCommand
     {
-        // ...
-
-        public function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(OutputInterface $output, #[Argument] string $username, #[Argument] string $password): int
         {
             $user = new User(...);
 
             $output->writeln([
-                'Username: '.$input->getArgument('username'),
-                'Password: '.$input->getArgument('password'),
+                'Username: '.$username,
+                'Password: '.$password,
             ]);
 
             // available methods: ->isSilent(), ->isQuiet(), ->isVerbose(), ->isVeryVerbose(), ->isDebug()
diff --git a/logging/monolog_console.rst b/logging/monolog_console.rst
index 67bf0f5acae..4d007abe854 100644
--- a/logging/monolog_console.rst
+++ b/logging/monolog_console.rst
@@ -10,10 +10,9 @@ When a lot of logging has to happen, it's cumbersome to print information
 depending on the verbosity settings (``-v``, ``-vv``, ``-vvv``) because the
 calls need to be wrapped in conditions. For example::
 
-    use Symfony\Component\Console\Input\InputInterface;
     use Symfony\Component\Console\Output\OutputInterface;
 
-    protected function execute(InputInterface $input, OutputInterface $output): int
+    public function __invoke(OutputInterface $output): int
     {
         if ($output->isDebug()) {
             $output->writeln('Some info');
@@ -34,23 +33,22 @@ the current log level and the console verbosity.
 
 The example above could then be rewritten as::
 
-    // src/Command/YourCommand.php
+    // src/Command/MyCommand.php
     namespace App\Command;
 
     use Psr\Log\LoggerInterface;
+    use Symfony\Component\Console\Attribute\AsCommand;
     use Symfony\Component\Console\Command\Command;
-    use Symfony\Component\Console\Input\InputInterface;
-    use Symfony\Component\Console\Output\OutputInterface;
 
-    class YourCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
     {
         public function __construct(
             private LoggerInterface $logger,
         ) {
-            parent::__construct();
         }
 
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(): int
         {
             $this->logger->debug('Some info');
             $this->logger->notice('Some more info');
diff --git a/reference/attributes.rst b/reference/attributes.rst
index eb09f4aa6bc..968c7df1568 100644
--- a/reference/attributes.rst
+++ b/reference/attributes.rst
@@ -14,7 +14,7 @@ Doctrine Bridge
 Command
 ~~~~~~~
 
-* :ref:`AsCommand <console_registering-the-command>`
+* :ref:`AsCommand <console_creating-command>`
 
 Contracts
 ~~~~~~~~~
diff --git a/routing.rst b/routing.rst
index bf3946b343d..f299fb5140d 100644
--- a/routing.rst
+++ b/routing.rst
@@ -2669,23 +2669,23 @@ The solution is to configure the ``default_uri`` option to define the
 
 Now you'll get the expected results when generating URLs in your commands::
 
-    // src/Command/SomeCommand.php
+    // src/Command/MyCommand.php
     namespace App\Command;
 
-    use Symfony\Component\Console\Command\Command;
-    use Symfony\Component\Console\Input\InputInterface;
-    use Symfony\Component\Console\Output\OutputInterface;
+    use Symfony\Component\Console\Attribute\AsCommand;
+    use Symfony\Component\Console\Style\SymfonyStyle;
     use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
     // ...
 
-    class SomeCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
     {
-        public function __construct(private UrlGeneratorInterface $urlGenerator)
-        {
-            parent::__construct();
+        public function __construct(
+            private UrlGeneratorInterface $urlGenerator,
+        ) {
         }
 
-        protected function execute(InputInterface $input, OutputInterface $output): int
+        public function __invoke(SymfonyStyle $io): int
         {
             // generate a URL with no route arguments
             $signUpPage = $this->urlGenerator->generate('sign_up');
diff --git a/scheduler.rst b/scheduler.rst
index 59dfa121361..3bf6735b1e0 100644
--- a/scheduler.rst
+++ b/scheduler.rst
@@ -478,7 +478,8 @@ The attribute takes more parameters to customize the trigger::
     // when applying this attribute to a Symfony console command, you can pass
     // arguments and options to the command using the 'arguments' option:
     #[AsCronTask('0 0 * * *', arguments: 'some_argument --some-option --another-option=some_value')]
-    class MyCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
 
 .. _scheduler-attributes-periodic-task:
 
@@ -527,7 +528,8 @@ The ``#[AsPeriodicTask]`` attribute takes many parameters to customize the trigg
     // when applying this attribute to a Symfony console command, you can pass
     // arguments and options to the command using the 'arguments' option:
     #[AsPeriodicTask(frequency: '1 day', arguments: 'some_argument --some-option --another-option=some_value')]
-    class MyCommand extends Command
+    #[AsCommand(name: 'app:my-command')]
+    class MyCommand
 
 Managing Scheduled Messages
 ---------------------------

From 26050d0675ef582764b497129d2be55621b562b9 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 1 Jul 2025 12:34:44 +0200
Subject: [PATCH 733/747] Minor tweaks

---
 components/console/helpers/formatterhelper.rst | 2 +-
 console.rst                                    | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/components/console/helpers/formatterhelper.rst b/components/console/helpers/formatterhelper.rst
index 4f83e66eecc..cf9bacdeb9c 100644
--- a/components/console/helpers/formatterhelper.rst
+++ b/components/console/helpers/formatterhelper.rst
@@ -3,7 +3,7 @@ Formatter Helper
 
 The :class:`Symfony\\Component\\Console\\Helper\\FormatterHelper` helper provides
 functions to format the output with colors. You can do more advanced things with
-this helper than you can in :doc:`/console/coloring`::
+this helper than you can with the :doc:`basic colors and styles </console/coloring>`::
 
     $formatter = new FormatterHelper();
 
diff --git a/console.rst b/console.rst
index 4a4161a2014..a3d6701f47c 100644
--- a/console.rst
+++ b/console.rst
@@ -112,8 +112,8 @@ completion (by default, by pressing the Tab key).
 Creating a Command
 ------------------
 
-Commands are defined in classes, for example, you may want a command to create a user. Use
-the ``#[AsCommand]`` attribute to auto-register it::
+Commands are defined in classes and auto-registered using the ``#[AsCommand]``
+attribute. For example, you may want a command to create a user::
 
     // src/Command/CreateUserCommand.php
     namespace App\Command;
@@ -412,7 +412,7 @@ command:
     Note that it will not be called when the command is run without interaction
     (e.g. when passing the ``--no-interaction`` global option flag).
 
-``__invoke()`` *(required)*
+``__invoke()`` (or :method:`Symfony\\Component\\Console\\Command\\Command::execute`) *(required)*
     This method is executed after ``interact()`` and ``initialize()``.
     It contains the logic you want the command to execute and it must
     return an integer which will be used as the command `exit status`_.

From 09bb042d326305318214504f68ce24c451944fb3 Mon Sep 17 00:00:00 2001
From: Victor Dittiere <victor.dittiere@icloud.com>
Date: Thu, 3 Jul 2025 14:54:04 +0200
Subject: [PATCH 734/747] Update encoders.rst

Fix classname comment in `Creating a Custom Encoder` section
---
 serializer/encoders.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/serializer/encoders.rst b/serializer/encoders.rst
index d2cf1f9cab8..8238d4d057d 100644
--- a/serializer/encoders.rst
+++ b/serializer/encoders.rst
@@ -271,7 +271,7 @@ Creating a Custom Encoder
 Imagine you want to serialize and deserialize `NEON`_. For that you'll have to
 create your own encoder::
 
-    // src/Serializer/YamlEncoder.php
+    // src/Serializer/NeonEncoder.php
     namespace App\Serializer;
 
     use Nette\Neon\Neon;

From a80ff3192cfcd3398419ee8214877a06ae58b800 Mon Sep 17 00:00:00 2001
From: Indra Gunawan <hello@indra.my.id>
Date: Sat, 5 Jul 2025 17:45:45 +0800
Subject: [PATCH 735/747] update enumClass to enumFqcn

---
 components/config/definition.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/components/config/definition.rst b/components/config/definition.rst
index 4848af33ffe..2b1841bc24a 100644
--- a/components/config/definition.rst
+++ b/components/config/definition.rst
@@ -186,14 +186,14 @@ The configuration can now be written like this::
         ->end()
     ;
 
-You can also use the ``enumClass()`` method to pass the FQCN of an enum
+You can also use the ``enumFqcn()`` method to pass the FQCN of an enum
 class to the node. This will automatically set the values of the node to
 the cases of the enum::
 
     $rootNode
         ->children()
             ->enumNode('delivery')
-                ->enumClass(Delivery::class)
+                ->enumFqcn(Delivery::class)
             ->end()
         ->end()
     ;
@@ -203,7 +203,7 @@ to one of the enum cases if possible.
 
 .. versionadded:: 7.3
 
-    The ``enumClass()`` method was introduced in Symfony 7.3.
+    The ``enumFqcn()`` method was introduced in Symfony 7.3.
 
 Array Nodes
 ~~~~~~~~~~~

From b0d3f221e90ef9ed0c54693dd0548a41b9ce0992 Mon Sep 17 00:00:00 2001
From: Aubert Jordan <jordan@les-tilleuls.coop>
Date: Tue, 8 Jul 2025 14:53:53 +0200
Subject: [PATCH 736/747] Fix Mailer #21190 : Update documentation about
 `allowed_recipients` behaviour

---
 mailer.rst | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index bbb9f18595c..cbd671b36d5 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -1926,9 +1926,8 @@ a specific address, instead of the *real* address:
             ;
         };
 
-Use the ``allowed_recipients`` option to specify exceptions to the behavior defined
-in the ``recipients`` option; allowing emails directed to these specific recipients
-to maintain their original destination:
+Use the ``allowed_recipients`` option to specify a "whitelist": this will allow emails directed to these specific recipients
+to maintain their original destination, as well as being sent to the destinations defined in ``recipients``:
 
 .. configuration-block::
 
@@ -1988,8 +1987,8 @@ to maintain their original destination:
         };
 
 With this configuration, all emails will be sent to ``youremail@example.com``,
-except for those sent to ``internal@example.com``, ``internal-monitoring@example.fr``,
-etc., which will receive emails as usual.
+and in addition, those sent to ``internal@example.com``, ``internal-monitoring@example.fr``,
+etc., will receive emails as usual.
 
 .. versionadded:: 7.1
 

From 45022151c7244ca2326aec3cbc91233f7f73b0bf Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 9 Jul 2025 13:18:31 +0200
Subject: [PATCH 737/747] Minor tweaks

---
 mailer.rst | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/mailer.rst b/mailer.rst
index cbd671b36d5..4aa989c39a5 100644
--- a/mailer.rst
+++ b/mailer.rst
@@ -1926,8 +1926,9 @@ a specific address, instead of the *real* address:
             ;
         };
 
-Use the ``allowed_recipients`` option to specify a "whitelist": this will allow emails directed to these specific recipients
-to maintain their original destination, as well as being sent to the destinations defined in ``recipients``:
+Use the ``allowed_recipients`` option to define specific addresses that should
+still receive their original emails. These messages will also be sent to the
+address(es) defined in ``recipients``, as with all other emails:
 
 .. configuration-block::
 
@@ -1986,9 +1987,9 @@ to maintain their original destination, as well as being sent to the destination
             ;
         };
 
-With this configuration, all emails will be sent to ``youremail@example.com``,
-and in addition, those sent to ``internal@example.com``, ``internal-monitoring@example.fr``,
-etc., will receive emails as usual.
+With this configuration, all emails will be sent to ``youremail@example.com``.
+Additionally, emails sent to ``internal@example.com``, ``internal-monitoring@example.fr``,
+etc., will also be delivered to those addresses.
 
 .. versionadded:: 7.1
 

From 0cb7c166611913c6b4246baf8fde0c4d910cd0db Mon Sep 17 00:00:00 2001
From: Mimi <160484490+hmeknassi@users.noreply.github.com>
Date: Mon, 14 Jul 2025 09:32:47 +0200
Subject: [PATCH 738/747] Update lock.rst

Adds a clarification in the Lock component documentation about the the values to use for the env variable LOCK_DSN in order to activate the NullStore and the InMemoryStore.
---
 components/lock.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/components/lock.rst b/components/lock.rst
index b8ba38c8fc7..1bcdc51f80e 100644
--- a/components/lock.rst
+++ b/components/lock.rst
@@ -405,7 +405,8 @@ Store                                                       Scope   Blocking  Ex
 
     Symfony includes two other special stores that are mostly useful for testing:
     ``InMemoryStore``, which saves locks in memory during a process, and ``NullStore``,
-    which doesn't persist anything.
+    which doesn't persist anything. To activate either one, simply set the ``LOCK_DSN`` to
+    ``null`` or ``in-memory``.
 
 .. versionadded:: 7.2
 

From df56c8e54dc921cc400af62c1fb9eedab09a7687 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Tue, 15 Jul 2025 09:04:44 +0200
Subject: [PATCH 739/747] Tweaks

---
 components/lock.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/components/lock.rst b/components/lock.rst
index 1bcdc51f80e..8d50a0c297e 100644
--- a/components/lock.rst
+++ b/components/lock.rst
@@ -404,9 +404,9 @@ Store                                                       Scope   Blocking  Ex
 .. tip::
 
     Symfony includes two other special stores that are mostly useful for testing:
-    ``InMemoryStore``, which saves locks in memory during a process, and ``NullStore``,
-    which doesn't persist anything. To activate either one, simply set the ``LOCK_DSN`` to
-    ``null`` or ``in-memory``.
+
+    * ``InMemoryStore`` (``LOCK_DSN=in-memory``), which saves locks in memory during a process;
+    * ``NullStore`` (``LOCK_DSN=null``) which doesn't persist anything.
 
 .. versionadded:: 7.2
 

From d1b52cb60de3fb00a7511d7cbda0e8f82af08c15 Mon Sep 17 00:00:00 2001
From: Samuel NELA <hello@samnela.com>
Date: Thu, 17 Jul 2025 22:25:24 +0200
Subject: [PATCH 740/747] [Setup] Use the stable version to create a new
 application

---
 setup.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/setup.rst b/setup.rst
index 20d71d112eb..dfc26901d74 100644
--- a/setup.rst
+++ b/setup.rst
@@ -48,10 +48,10 @@ application:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ symfony new my_project_directory --version="7.3.x-dev" --webapp
+    $ symfony new my_project_directory --version="7.3.x" --webapp
 
     # run this if you are building a microservice, console application or API
-    $ symfony new my_project_directory --version="7.3.x-dev"
+    $ symfony new my_project_directory --version="7.3.x"
 
 The only difference between these two commands is the number of packages
 installed by default. The ``--webapp`` option installs extra packages to give
@@ -63,12 +63,12 @@ Symfony application using Composer:
 .. code-block:: terminal
 
     # run this if you are building a traditional web application
-    $ composer create-project symfony/skeleton:"7.3.x-dev" my_project_directory
+    $ composer create-project symfony/skeleton:"7.3.x" my_project_directory
     $ cd my_project_directory
     $ composer require webapp
 
     # run this if you are building a microservice, console application or API
-    $ composer create-project symfony/skeleton:"7.3.x-dev" my_project_directory
+    $ composer create-project symfony/skeleton:"7.3.x" my_project_directory
 
 No matter which command you run to create the Symfony application. All of them
 will create a new ``my_project_directory/`` directory, download some dependencies

From d50c1d481bfb0d469fae36e41b29b97b28bf7840 Mon Sep 17 00:00:00 2001
From: "Phil E. Taylor" <phil@phil-taylor.com>
Date: Wed, 23 Jul 2025 09:44:53 +0100
Subject: [PATCH 741/747] s/sytsem/system

---
 reference/configuration/doctrine.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/reference/configuration/doctrine.rst b/reference/configuration/doctrine.rst
index 2aa716ae9fc..db6336e1ee6 100644
--- a/reference/configuration/doctrine.rst
+++ b/reference/configuration/doctrine.rst
@@ -353,7 +353,7 @@ to cache each of Doctrine ORM elements (queries, results, etc.):
                     ->pool('doctrine.result_cache_pool')
                         ->adapters('cache.app')
                     ->pool('doctrine.system_cache_pool')
-                        ->adapters('cache.sytsem');
+                        ->adapters('cache.system');
 
             $doctrine->orm()
                 // ...

From 2bc78c16afa3e87c5e4cc90ce4808837ee5ecced Mon Sep 17 00:00:00 2001
From: ahmetkun <ahmetkun@gmail.com>
Date: Thu, 24 Jul 2025 23:11:49 +0300
Subject: [PATCH 742/747] Update rate_limiter.rst

---
 rate_limiter.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rate_limiter.rst b/rate_limiter.rst
index 3a517c37bd4..5fd453f0534 100644
--- a/rate_limiter.rst
+++ b/rate_limiter.rst
@@ -646,7 +646,7 @@ Then, inject and use as normal::
     use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
     use Symfony\Component\HttpFoundation\Request;
     use Symfony\Component\HttpFoundation\Response;
-    use Symfony\Component\RateLimiter\RateLimiterFactory;
+    use Symfony\Component\RateLimiter\RateLimiterFactoryInterface;
 
     class ContactController extends AbstractController
     {

From e946b313b5ce28a030874c88ba9486ef5724de6f Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Fri, 25 Jul 2025 13:20:13 +0200
Subject: [PATCH 743/747] Rewords

---
 serializer.rst                |  45 +++---
 serializer/streaming_json.rst | 277 ++++++++++++++++------------------
 2 files changed, 154 insertions(+), 168 deletions(-)

diff --git a/serializer.rst b/serializer.rst
index be31fc66a9e..eb06f1b34a1 100644
--- a/serializer.rst
+++ b/serializer.rst
@@ -629,37 +629,34 @@ all the properties of the class::
         // ...
     }
 
-Serializing JSON using streams
+Serializing JSON Using Streams
 ------------------------------
 
-Symfony is able of encoding PHP data structures to JSON streams and decoding
-JSON streams back into PHP data structures.
+Symfony can encode PHP data structures to JSON streams and decode JSON streams
+back into PHP data structures.
 
-To do so, it relies on the JsonStreamer component, which is designed for high
-efficiency and can process large JSON data incrementally without needing to
-load the entire content into memory.
+To do this, it relies on the :doc:`JsonStreamer component </serializer/streaming_json>`,
+which is designed for high efficiency and can process large JSON data incrementally,
+without needing to load the entire content into memory.
 
-When deciding between the :doc:`Serializer component <serializer>` and the
-JsonStreamer component, consider the following:
+When deciding between the Serializer component and the JsonStreamer component,
+consider the following:
 
-- **Serializer Component**: Ideal for scenarios requiring flexibility, such as
-  dynamically manipulating object shapes using normalizers and denormalizers,
-  or handling complex objects which multiple serialization representation.
-  Plus, it allows working with formats beyond JSON (and even with a custom
-  format of yours).
+* **Serializer Component**: Best suited for use cases that require flexibility,
+  such as dynamically manipulating object structures using normalizers and
+  denormalizers, or handling complex objects with multiple serialization
+  formats. It also supports output formats beyond JSON (including your own
+  custom ones).
+* **JsonStreamer Component**: Best suited for simple objects and scenarios that
+  demand high performance and low memory usage. It's particularly effective
+  for processing very large JSON datasets or when streaming JSON in real-time
+  without loading the entire dataset into memory.
 
-- **JsonStreamer Component**: Ideal for simple objects and tasks that
-  demand high performance and minimal memory usage. It's particularly
-  effective when processing very large JSON datasets or in scenarios that
-  require streaming JSON in real-time without loading the entire dataset
-  into memory.
+The choice depends on your specific use case. The JsonStreamer component is
+tailored for performance and memory efficiency, whereas the Serializer
+component provides greater flexibility and broader format support.
 
-Choosing between the two depends on your specific use case requirements.
-The JsonStreamer component is tailored to optimize for performance and memory
-efficiency, while the Serializer component offers flexibility and broader
-format support.
-
-Read more about streaming JSON in :doc:`/serializer/streaming_json`.
+Read more about :doc:`streaming JSON </serializer/streaming_json>`.
 
 Serializing to or from PHP Arrays
 ---------------------------------
diff --git a/serializer/streaming_json.rst b/serializer/streaming_json.rst
index 3cf4de3ef0b..3fd44824bc6 100644
--- a/serializer/streaming_json.rst
+++ b/serializer/streaming_json.rst
@@ -1,25 +1,28 @@
 Streaming JSON
 ==============
 
-Symfony is able of encoding PHP data structures to JSON streams and decoding
-JSON streams back into PHP data structures.
+.. versionadded:: 7.3
 
-To do so, it relies on the JsonStreamer component, which is designed for high
-efficiency and can process large JSON data incrementally without needing to
-load the entire content into memory.
+    The JsonStreamer component was introduced in Symfony 7.3 as an
+    :doc:`experimental feature </contributing/code/experimental>`.
 
-.. tip::
+Symfony can encode PHP data structures to JSON streams and decode JSON streams
+back into PHP data structures.
+
+To do so, it relies on the **JsonStreamer** component, which is designed for
+high efficiency and can process large JSON data incrementally without needing
+to load the entire content into memory.
 
-    This component is ideal for handling APIs or interacting with third-party
-    APIs. It transforms incoming JSON request payloads into PHP objects that
-    your application can work with. Similarly, it converts processed PHP
-    objects into a JSON stream for outgoing responses.
+This component is ideal for handling APIs or interacting with third-party APIs.
+It transforms incoming JSON request payloads into PHP objects that your
+application can work with. Similarly, it converts processed PHP objects into a
+JSON stream for outgoing responses.
 
 Installation
 ------------
 
-To install the JsonStreamer component in applications that use
-:ref:`Symfony Flex <symfony-flex>`, run this command:
+In applications using :ref:`Symfony Flex <symfony-flex>`, run this command to
+install the JsonStreamer component:
 
 .. code-block:: terminal
 
@@ -27,38 +30,43 @@ To install the JsonStreamer component in applications that use
 
 .. include:: /components/require_autoload.rst.inc
 
-.. warning::
-
-    The JsonStreamer component is :doc:`experimental </contributing/code/experimental>`
-    and could be changed at any time without prior notice.
-
-Encoding objects
+Encoding Objects
 ----------------
 
-Let's say that we have the following ``Cat`` class::
+JsonStreamer only works with PHP classes that have **no constructor** and are
+composed solely of **public properties**, like `DTO classes`_. Consider the
+following ``Cat`` class::
 
     // src/Dto/Cat.php
     namespace App\Dto;
 
-    use Symfony\Component\JsonStreamer\Attribute\JsonStreamable;
-
-    #[JsonStreamable]
     class Cat
     {
         public string $name;
         public string $age;
     }
 
-.. warning::
+To encode ``Cat`` objects into a JSON stream (e.g., to send them in an API
+response), first apply the ``#[JsonStreamable]`` attribute to the class. This
+attribute is optional, but it :ref:`improves performance <json-streamer-streamable-attribute>`
+by pre-generating encoding and decoding files during cache warm-up::
 
-    The JsonStreamer only works with PHP classes without constructor and
-    composed by public properties only.
+    namespace App\Dto;
 
-If you want to encode ``Cat`` objects to a JSON stream (e.g. to send them
-via an API response), you can get the ``json_streamer.stream_writer`` service by using
-the :class:`Symfony\\Component\\JsonStreamer\\StreamWriterInterface` parameter type
-with the ``$jsonStreamWriter`` name, and use the :method:`Symfony\\Component\\JsonStreamer\\StreamWriterInterface::write`
-method:
+    use Symfony\Component\JsonStreamer\Attribute\JsonStreamable;
+
+    #[JsonStreamable]
+    class Cat
+    {
+        // ...
+    }
+
+Next, inject the JSON stream writer into your service. The service ``id`` is
+``json_streamer.stream_writer``, but you can also get it by type-hinting a
+``$jsonStreamWriter`` argument with :class:`Symfony\\Component\\JsonStreamer\\StreamWriterInterface`.
+
+Use the :method:`Symfony\\Component\\JsonStreamer\\StreamWriterInterface::write`
+method of the service to perform the actual JSON conversion:
 
 .. configuration-block::
 
@@ -107,20 +115,21 @@ method:
 
         // ...
 
-.. note::
+.. tip::
 
     You can explicitly inject the ``json_streamer.stream_writer`` service by
     using the ``#[Target('json_streamer.stream_writer')]`` autowire attribute.
 
-Decoding objects
+Decoding Objects
 ----------------
 
-Besides encoding objects to JSON, you can decode JSON to objects.
+In addition to encoding, you can decode JSON into PHP objects.
 
-To do so, you can get the ``json_streamer.stream_reader`` service by using the
-:class:`Symfony\\Component\\JsonStreamer\\StreamReaderInterface` parameter type
-with the ``$jsonStreamReader`` name, and use the :method:`Symfony\\Component\\JsonStreamer\\StreamReaderInterface::read`
-method:
+To do this, inject the JSON stream reader into your service. The service ``id`` is
+``json_streamer.stream_reader``, but you can also get it by type-hinting a
+``$jsonStreamReader`` argument with :class:`Symfony\\Component\\JsonStreamer\\StreamReaderInterface`.
+Next, use the :method:`Symfony\\Component\\JsonStreamer\\StreamReaderInterface::read`
+method to perform the actual JSON parsing:
 
 .. configuration-block::
 
@@ -237,71 +246,56 @@ method:
             }
         }
 
-.. note::
+.. tip::
 
     You can explicitly inject the ``json_streamer.stream_reader`` service by
     using the ``#[Target('json_streamer.stream_reader')]`` autowire attribute.
 
-The upper code demonstrates two different approaches to decoding JSON data
-using the JsonStreamer:
+The examples above demonstrate two different approaches to decoding JSON data
+using JsonStreamer:
 
 * decoding from a stream (``pickTheTenthCat``)
-* decoding from a string (``listEligibleCatNames``).
-
-Both methods work with the same JSON data but differ in memory usage and
-speed optimization.
+* decoding from a string (``listEligibleCatNames``)
 
+Both methods handle the same JSON data but differ in memory usage and performance.
+Use streams if optimizing memory usage is more important. Use strings if
+performance is more important.
 
-Decoding from a stream
+Decoding from a Stream
 ~~~~~~~~~~~~~~~~~~~~~~
 
 In the ``pickTheTenthCat`` method, the JSON data is read as a stream using
-:phpfunction:`fopen`. Streams are useful when working with large files
-because the data is processed incrementally rather than loading the entire
-file into memory.
+:phpfunction:`fopen`. This is useful for large files, as the data is processed
+incrementally rather than being fully loaded into memory.
 
-To improve memory efficiency, the JsonStreamer creates `ghost objects`_
-instead of fully instantiating objects. Ghosts objects are lightweight
-placeholders that represent the objects but don't fully load their data
-into memory until it's needed. This approach reduces memory usage, especially
-for large datasets.
+To optimize memory usage, JsonStreamer creates `ghost objects`_ instead of
+fully instantiating them. These lightweight placeholders delay object creation
+until the data is actually needed.
 
-* Advantage: Efficient memory usage, suitable for very large JSON files.
-* Disadvantage: Slightly slower than decoding a full string because data is
-  loaded on-demand.
+* Advantage: Efficient memory usage, ideal for very large JSON files.
+* Disadvantage: Slightly slower due to lazy loading.
 
-Decoding from a string
+Decoding from a String
 ~~~~~~~~~~~~~~~~~~~~~~
 
-In the ``listEligibleCatNames`` method, the entire JSON file is read into
-a string using :phpfunction:`file_get_contents`. This string is then passed
-to the decoder, which fully instantiates all the objects in the JSON data
-upfront.
+In the ``listEligibleCatNames`` method, the entire JSON file is read into a
+string using :phpfunction:`file_get_contents`. The decoder then instantiates
+all the objects immediately.
 
-This approach is faster because all the objects are created immediately,
-making subsequent operations on the data quicker. However, it uses more
-memory since the entire file content and all objects are loaded at once.
+This approach is faster because all objects are created immediately, but it
+requires more memory.
 
-* Advantage: Faster processing, suitable for small to medium-sized JSON files.
-* Disadvantage: Higher memory usage, not ideal for large JSON files.
+* Advantage: Faster, ideal for small to medium JSON files.
+* Disadvantage: Higher memory usage, unsuitable for large files.
 
-.. tip::
-
-    Prefer stream decoding when working with large JSON files to conserve
-    memory.
-
-    Prefer string decoding instead when performance is more critical and the
-    JSON file size is manageable.
-
-Enabling PHPDoc reading
+Enabling PHPDoc Reading
 -----------------------
 
-The JsonStreamer component can be able to process advanced PHPDoc type
-definitions, such as generics, and read/generate JSON for complex PHP
-objects.
+The JsonStreamer component can read advanced PHPDoc type definitions (e.g.,
+generics) and process complex PHP objects accordingly.
 
-For example, let's consider this ``Shelter`` class that defines a generic
-``TAnimal`` type, which can be a ``Cat`` or a ``Dog``::
+Consider the ``Shelter`` class that defines a generic ``TAnimal`` type, which
+can be a ``Cat`` or a ``Dog``::
 
     // src/Dto/Shelter.php
     namespace App\Dto;
@@ -320,16 +314,15 @@ For example, let's consider this ``Shelter`` class that defines a generic
         public array $animals;
     }
 
-
-To enable PHPDoc interpretation, run the following command:
+To enable PHPDoc parsing, run:
 
 .. code-block:: terminal
 
     $ composer require phpstan/phpdoc-parser
 
-Then, when encoding/decoding an instance of the ``Shelter`` class, you can
-specify the concrete type information, and the JsonStreamer will deal with the
-correct JSON structure::
+Then, when encoding/decoding a ``Shelter`` instance, you can specify the
+concrete type information, and JsonStreamer will correctly interpret the JSON
+structure::
 
     use App\Dto\Cat;
     use App\Dto\Shelter;
@@ -349,18 +342,17 @@ correct JSON structure::
 
     $catShelter = $jsonStreamReader->read($json, $type); // will be populated with Cat instances
 
-Configuring encoding/decoding
+Configuring Encoding/Decoding
 -----------------------------
 
-While it's not recommended to change to object shape and values during
-encoding and decoding, it is sometimes unavoidable.
+While it's usually best not to alter the shape or values of objects during
+serialization, sometimes it's necessary.
 
-Configuring the encoded name
+Configuring the Encoded Name
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-It is possible to configure the JSON key associated to a property thanks to
-the :class:`Symfony\\Component\\JsonStreamer\\Attribute\\StreamedName`
-attribute::
+You can configure the JSON key for a property using the
+:class:`Symfony\\Component\\JsonStreamer\\Attribute\\StreamedName` attribute::
 
     // src/Dto/Duck.php
     namespace App\Dto;
@@ -375,7 +367,7 @@ attribute::
         public string $id;
     }
 
-By doing so, the ``Duck::$id`` property will be mapped to the ``@id`` JSON key::
+This maps the ``Duck::$id`` property to the ``@id`` JSON key::
 
     use App\Dto\Duck;
     use Symfony\Component\TypeInfo\Type;
@@ -392,19 +384,20 @@ By doing so, the ``Duck::$id`` property will be mapped to the ``@id`` JSON key::
     //   "@id": "/ducks/daffy"
     // }
 
-Configuring the encoded value
+Configuring the Encoded Value
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-If you need to manipulate the value related to a property during the encoding
-process, you can use the :class:`Symfony\\Component\\JsonStreamer\\Attribute\\ValueTransformer`
-attribute. Its ``nativeToStream`` property takes a callable, or a :ref:`value transformer service id <json-streamer-transform-with-services>`.
+To transform a property's value during encoding, use the
+:class:`Symfony\\Component\\JsonStreamer\\Attribute\\ValueTransformer`
+attribute. Its ``nativeToStream`` option accepts a callable or a
+:ref:`value transformer service id <json-streamer-transform-with-services>`.
 
-When a callable is specified, it must either be a public static method or
-non-anonymous function with the following signature::
+The callable must be a public static method or non-anonymous function with this
+signature::
 
     $transformer = function (mixed $data, array $options = []): mixed { /* ... */ };
 
-Then, you just have to specify the function identifier in the attribute::
+Then specify it in the attribute::
 
     // src/Dto/Duck.php
     namespace App\Dto;
@@ -427,8 +420,8 @@ Then, you just have to specify the function identifier in the attribute::
         }
     }
 
-For example, by configuring the ``Duck`` class like above, the ``name`` and
-``height`` values will be transformed during encoding::
+The following example transforms the ``name`` and ``height`` properties during
+encoding::
 
     use App\Dto\Duck;
     use Symfony\Component\TypeInfo\Type;
@@ -447,19 +440,20 @@ For example, by configuring the ``Duck`` class like above, the ``name`` and
     //   "height": "50.83cm"
     // }
 
-Configuring the decoded value
+Configuring the Decoded Value
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-You can as well manipulate the value related to a property during decoding
-using the :class:`Symfony\\Component\\JsonStreamer\\Attribute\\ValueTransformer`
-attribute. Its ``streamToNative`` property can take either a callable or a :ref:`value transformer service id <json-streamer-transform-with-services>`.
+To transform a property's value during decoding, use the
+:class:`Symfony\\Component\\JsonStreamer\\Attribute\\ValueTransformer`
+attribute. Its ``streamToNative`` option accepts a callable or a
+:ref:`value transformer service id <json-streamer-transform-with-services>`.
 
-When a callable is specified, it must either be a public static method or
-a non-anonymous function with the following signature::
+The callable must be a public static method or non-anonymous function with this
+signature::
 
     $valueTransformer = function (mixed $data, array $options = []): mixed { /* ... */ };
 
-You can specify a function identifier in the attribute as follows::
+Then specify it in the attribute::
 
     // src/Dto/Duck.php
     namespace App\Dto;
@@ -487,8 +481,7 @@ You can specify a function identifier in the attribute as follows::
         }
     }
 
-For instance, the above configuration for the ``Duck`` class will transform
-the `name` property from the input JSON during decoding::
+This will extract first and last names from a full name in the input JSON::
 
     use App\Dto\Duck;
     use Symfony\Component\TypeInfo\Type;
@@ -508,13 +501,11 @@ the `name` property from the input JSON during decoding::
 
 .. _json-streamer-transform-with-services:
 
-Transform value using services
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When static methods or functions are not enough, you can transform the value
-thanks to a value transformer service.
+Transforming Value Using Services
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-To do so, create a service implementing the :class:`Symfony\\Component\\JsonStreamer\\ValueTransformer\\ValueTransformerInterface`::
+When callables are not enough, you can use a service implementing the
+:class:`Symfony\\Component\\JsonStreamer\\ValueTransformer\\ValueTransformerInterface`::
 
     // src/Transformer/DogUrlTransformer.php
     namespace App\Transformer;
@@ -547,11 +538,10 @@ To do so, create a service implementing the :class:`Symfony\\Component\\JsonStre
 
 .. note::
 
-    The ``getStreamValueType`` method should return the type of what the value
-    will be in the JSON stream.
+    The ``getStreamValueType()`` method must return the value's type as it will
+    appear in the JSON stream.
 
-And then, configure the :class:`Symfony\\Component\\JsonStreamer\\Attribute\\ValueTransformer`
-attribute to use that service::
+To use this transformer in a class, configure the ``#[ValueTransformer]`` attribute::
 
     // src/Dto/Dog.php
     namespace App\Dto;
@@ -571,18 +561,18 @@ attribute to use that service::
 
 .. tip::
 
-    The value transformers will be intensively called during the
-    decoding and encoding. So be sure to keep them as fast as possible
-    (avoid calling external APIs or the database for example).
+    Value transformers are called frequently during encoding and decoding. Keep
+    them lightweight and avoid calls to external APIs or the database.
 
-Configure keys and values dynamically
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Configuring Keys and Values Dynamically
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The JsonStreamer leverages services implementing the :class:`Symfony\\Component\\JsonStreamer\\Mapping\\PropertyMetadataLoaderInterface`
-to determine the shape and values of objects during encoding/decoding.
+JsonStreamer uses services that implement the
+:class:`Symfony\\Component\\JsonStreamer\\Mapping\\PropertyMetadataLoaderInterface`
+to control the shape and values of objects during encoding/decoding.
 
-These services are highly flexible and can be decorated to handle dynamic
-configurations, offering much greater power compared to using attributes::
+These services are highly flexible and can be decorated to support dynamic
+configurations, providing more flexibility than attributes::
 
     namespace App\Streamer\SensitivePropertyMetadataLoader;
 
@@ -644,25 +634,23 @@ configurations, offering much greater power compared to using attributes::
         }
     }
 
-However, this flexibility comes with complexity. Decorating property metadata
-loaders requires a deep understanding of the system.
+Although powerful, this approach introduces complexity. Decorating property
+metadata loaders requires a deep understanding of the internals.
+
+For most use cases, attribute-based configuration is sufficient. Reserve
+dynamic loaders for advanced scenarios.
 
-For most use cases, the attributes approach is sufficient, and the dynamic
-capabilities of property metadata loaders should be reserved for scenarios
-where their additional power is genuinely necessary.
+.. _json-streamer-streamable-attribute:
 
-Marking objects as streamable
+Marking Objects as Streamable
 -----------------------------
 
-The ``JsonStreamable`` attribute is used to mark a class as streamable.
-While this attribute is not mandatory, it is highly recommended because it
-plays a crucial role during the cache warm-up process by generating the
-files necessary for encoding and decoding operations, and thereby improving
-performance.
+The ``JsonStreamable`` attribute marks a class as streamable. While not strictly
+required, it's highly recommended because it enables cache warm-up to pre-generate
+encoding/decoding files, improving performance.
 
-It includes two properties: ``asObject`` and ``asList``. These properties
-define the structure in which the marked class should be prepared during the
-cache warm-up process::
+It includes two optional properties: ``asObject`` and ``asList``, which define
+how the class should be prepared during cache warm-up::
 
     use Symfony\Component\JsonStreamer\Attribute\JsonStreamable;
 
@@ -672,4 +660,5 @@ cache warm-up process::
         // ...
     }
 
+.. _`DTO classes`: https://en.wikipedia.org/wiki/Data_transfer_object
 .. _ghost objects: https://en.wikipedia.org/wiki/Lazy_loading#Ghost

From 8bf25c84a2a9f58c99d02c5938266dbfec7ba012 Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Mon, 28 Jul 2025 08:43:50 +0200
Subject: [PATCH 744/747] Readd String component URL redirection

---
 _build/redirection_map | 1 +
 1 file changed, 1 insertion(+)

diff --git a/_build/redirection_map b/_build/redirection_map
index 560f241b93c..c30723eac58 100644
--- a/_build/redirection_map
+++ b/_build/redirection_map
@@ -575,6 +575,7 @@
 /doctrine/reverse_engineering /doctrine#doctrine-adding-mapping
 /components/serializer /serializer
 /serializer/custom_encoder /serializer/encoders#serializer-custom-encoder
+/components/string /string
 /form/button_based_validation /form/validation_groups
 /form/data_based_validation /form/validation_groups
 /form/validation_group_service_resolver /form/validation_groups

From 5c9b8735424af532b1242e5ed3525afb8f4a3bc7 Mon Sep 17 00:00:00 2001
From: Jan Rosier <jan.rosier@gmail.com>
Date: Tue, 29 Jul 2025 17:57:44 +0200
Subject: [PATCH 745/747] Update sreencast title

---
 page_creation.rst | 4 ++--
 setup.rst         | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/page_creation.rst b/page_creation.rst
index 3315dff279d..0e2fd78e180 100644
--- a/page_creation.rst
+++ b/page_creation.rst
@@ -18,7 +18,7 @@ two-step process:
 .. admonition:: Screencast
     :class: screencast
 
-    Do you prefer video tutorials? Check out the `Harmonious Development with Symfony`_
+    Do you prefer video tutorials? Check out the `Cosmic Coding with Symfony`_
     screencast series.
 
 .. seealso::
@@ -302,5 +302,5 @@ Go Deeper with HTTP & Framework Fundamentals
 
 .. _`Twig`: https://twig.symfony.com
 .. _`Composer`: https://getcomposer.org
-.. _`Harmonious Development with Symfony`: https://symfonycasts.com/screencast/symfony/setup
+.. _`Cosmic Coding with Symfony`: https://symfonycasts.com/screencast/symfony/setup
 .. _`attributes`: https://www.php.net/manual/en/language.attributes.overview.php
diff --git a/setup.rst b/setup.rst
index f78d8047dfd..0f103ce476d 100644
--- a/setup.rst
+++ b/setup.rst
@@ -4,7 +4,7 @@ Installing & Setting up the Symfony Framework
 .. admonition:: Screencast
     :class: screencast
 
-    Do you prefer video tutorials? Check out the `Harmonious Development with Symfony`_
+    Do you prefer video tutorials? Check out the `Cosmic Coding with Symfony`_
     screencast series.
 
 .. _symfony-tech-requirements:
@@ -311,7 +311,7 @@ Learn More
     setup/web_server_configuration
     setup/*
 
-.. _`Harmonious Development with Symfony`: https://symfonycasts.com/screencast/symfony
+.. _`Cosmic Coding with Symfony`: https://symfonycasts.com/screencast/symfony
 .. _`Install Composer`: https://getcomposer.org/download/
 .. _`install the Symfony CLI`: https://symfony.com/download
 .. _`symfony-cli/symfony-cli GitHub repository`: https://github.com/symfony-cli/symfony-cli

From 75cc14558e0ee5984dc673156fbf8273bcfba1c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Marinetti?= <github@marinetti.fr>
Date: Wed, 30 Jul 2025 11:35:26 +0200
Subject: [PATCH 746/747] minor #21259 add missing use in code example

---
 routing.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/routing.rst b/routing.rst
index 4f34e084d61..69e6cebb01c 100644
--- a/routing.rst
+++ b/routing.rst
@@ -1559,6 +1559,7 @@ This way, the ``product_show`` alias could be deprecated.
         namespace App\Controller;
 
         use Symfony\Component\HttpFoundation\Response;
+        use Symfony\Component\Routing\Attribute\DeprecatedAlias;
         use Symfony\Component\Routing\Attribute\Route;
 
         class ProductController

From 96c1e2d94d1139a9e5a2e106542a30fd48e9387e Mon Sep 17 00:00:00 2001
From: Javier Eguiluz <javier.eguiluz@gmail.com>
Date: Wed, 30 Jul 2025 15:10:03 +0200
Subject: [PATCH 747/747] Add a missing versionadded directive

---
 routing.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/routing.rst b/routing.rst
index 69e6cebb01c..9925b323304 100644
--- a/routing.rst
+++ b/routing.rst
@@ -1661,6 +1661,10 @@ This way, the ``product_show`` alias could be deprecated.
             )
         ;
 
+.. versionadded:: 7.3
+
+    The ``DeprecatedAlias`` class for PHP attributes was introduced in Symfony 7.3.
+
 In this example, every time the ``product_show`` alias is used, a deprecation
 warning is triggered, advising you to stop using this route and prefer using ``product_details``.
 
